What is a security token?
“Security token” URLs were added in cPanel & WHM 11.25 as a security measure, and they were enabled by default in version 11.28. They help combat a common type of attack called a Cross-Site Request Forgery (XSRF).
So, what does a “security token” look like? Take, for example, this URL:
https://example.com:2087/i/love/cpanel
With security tokens enabled, this would become:
https://example.com:2087/cpsessYYYYYYY/i/love/cpanel
In that example, cpsessYYYYYYY is the token unique to that logged-in user on that browser. (You can learn more about security tokens in cPanel & WHM by reading our Security Tokens white paper.) In order for your custom script to work with cPanel & WHM, every URL involved needs to be compatible with the security token.
Creating security token-compatible URLs
Fortunately, it is very easy to do!
The token is available in the environment variable ‘cp_security_token’.
If security tokens are not in use, ‘cp_security_token’ will be an empty string.
If security tokens are in use, ‘cp_security_token’ will be, in terms of the above example: /cpsessYYYYYYY
Note the preceding slash! Since the variable has that slash, the examples will work whether cPanel & WHM has security tokens enabled or disabled.
- Here’s how you’d use it in Perl code that calls one of our API URLS.
Simply change this:my $APIurl = "http://127.0.0.1:2087/xml-api/$url";
to this:
my $APIurl = "http://127.0.0.1:2087$ENV{'cp_security_token'}/xml-api/$url";
- Here’s how you might use it in JavaScript for, say, an AJAX call.
First, make it available to your JavaScript. For example:print <<"END_SECURITY_TOKEN_JAVASCRIPT";
if ( !("CPANEL" in window) ) CPANEL = {};
CPANEL.security_token = "$ENV{'cp_security_token'}";END_SECURITY_TOKEN_JAVASCRIPT
Next, make your URLs compatible by changing this:
var ajaxURL = '/3rdparty/ZZZ/zzz.cgi';
to this:
var ajaxURL = CPANEL.security_token + '/3rdparty/ZZZ/zzz.cgi';
I’m sorry for being so ignorant, but I can’t work out where and how you would use these ‘codes’. I have multiple websites and open Awstats via CPanel for all of them on a daily basis using group launch. Previously all I had to do is hit the Enter key for each one and they opened, now I have to paste the password for each site. I would love a simple way to disable these annoying tokens. Can you help, please?
I use this code to generate new email box via cpanel. For previous versions of Cpanel we have no need in security token and for now we need it by default. What I’m doing wrong with security token generation or why email box could not be created. whm hash is correct 100%.
I see $ENV{‘cp_security_token’} with variable $ENV but if we insert it in the php code we will get an error that this variable is not defined!
Look forward to hearing from you.
Thanks
$cpanel_username = $this->config->item(‘cpanel_username’);
$cpanel_domain = $this->config->item(‘cpanel_domain’);
$case_email = ‘case’ . $case_number;
$case_email_password = $this->config->item(‘zenfile_default_email_password’);
$url = ‘67.139.36.73:2087{“cp_security_token”}’;
$hash = ‘whm hash here for access’;
$query = ‘https://’.$url.’/json-api/cpanel?cpanel_jsonapi_user=’ . $cpanel_username . ‘&cpanel_jsonapi_module=Email&cpanel_jsonapi_func=addpop&cpanel_jsonapi_apiversion=1&arg-0=’ . $case_email . ‘&arg-1=’ . $case_email_password . ‘&arg-2=0&arg-3=’ . $cpanel_domain;
$curl = curl_init();
$header[0] = “Authorization: WHM root:” . preg_replace(“‘(r|n)'”, “”, $hash);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
# Create Curl Object
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
# Allow self-signed certs
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
# Allow certs that do not match the hostname
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, 0);
# Do not include header in output
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
# Return contents of transfer on curl_exec
# set the username and password
curl_setopt($curl, CURLOPT_URL, $query);
# execute the query
$result = curl_exec($curl);
curl_close($curl);
Howdie do,
Can you explain how you would do this for a PHP script?
I currently have:
$query =”https://(IP)/$ENV{‘cp_security_token’}/xml-api/createacct?username=$hookuser&domain=$hookdomain&password=$hookpassword”;
Glad the information was helpful to you. Appreciate the feedback!
Thank you very much! really helpful this detailed explanation!