1

I'm trying to create a login action using CURL with PHP in a form with CSRF token.

The form is located at this address: https://example.com/account/login and the action of the form refers to: https://example.com/account/login

If I try it from my local server to remote address, it works perfectly. If I try it from remote server to the same address, it doesn't work. What I need to check in your opinion?

This is my code:

//URL of the login form.
define('LOGIN_FORM_URL', 'https://example.com/account/login');

//Login action URL. Sometimes, this is the same URL as the login form.
define('LOGIN_ACTION_URL', 'https://example.com/account/login');

//Initiate cURL.
$this->curl = curl_init(LOGIN_ACTION_URL);

//Tells cURL to return the output once the request has been executed.
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);

//Do we want to follow any redirects?
curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true);

curl_setopt($this->curl, CURLOPT_AUTOREFERER, true);


//Where our cookie details are saved. This is typically required
//for authentication, as the session ID is usually saved in the cookie file.
curl_setopt($this->curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
curl_setopt($this->curl, CURLOPT_COOKIEFILE, COOKIE_FILE);

//Sets the user agent. Some websites will attempt to block bot user agents.
//Hence the reason I gave it a Chrome user agent.
curl_setopt($this->curl, CURLOPT_USERAGENT, USER_AGENT);

//We don't want any HTTPS errors.
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);

//Execute the login request.
$resultLogin = curl_exec($this->curl);

$dom = new DomDocument();
    $token = '';
    libxml_use_internal_errors(true);
    $dom->loadHTML($resultLogin);
    $tokens = $dom->getElementsByTagName("input");
    for ($i = 0; $i < $tokens->length; $i++) {
        $meta = $tokens->item($i);
        if ($meta->getAttribute('name') === '_csrf_token')
            $token = $meta->getAttribute('value');
    }

    $postValues = array(
        'username' => $this->username,
        'password' => $this->password,
        'login' => '',
        '_csrf_token' => $token
    );

        //Set the URL that we want to send our POST request to. In this
    //case, it's the action URL of the login form.
    curl_setopt($this->curl, CURLOPT_URL, LOGIN_ACTION_URL);
    curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);

    //Tell cURL that we want to carry out a POST request.
    curl_setopt($this->curl, CURLOPT_POST, true);

    //Set our post fields / date (from the array above).
    //curl_setopt($this->curl, CURLOPT_POSTFIELDS, http_build_query($postValues));
    curl_setopt($this->curl, CURLOPT_POSTFIELDS, http_build_query($postValues));

    // Add headers
    curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);

    //We don't want any HTTPS errors.
    curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);

    //Where our cookie details are saved. This is typically required
    //for authentication, as the session ID is usually saved in the cookie file.
    curl_setopt($this->curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
    curl_setopt($this->curl, CURLOPT_COOKIEFILE, COOKIE_FILE);

    //Sets the user agent. Some websites will attempt to block bot user agents.
    //Hence the reason I gave it a Chrome user agent.
    curl_setopt($this->curl, CURLOPT_USERAGENT, USER_AGENT);

    //Tells cURL to return the output once the request has been executed.
    curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);

    //Allows us to set the referer header. In this particular case, we are
    //fooling the server into thinking that we were referred by the login form.
    curl_setopt($this->curl, CURLOPT_REFERER, LOGIN_FORM_URL);

    //Do we want to follow any redirects?
    curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true);
    $resultLogin2 = curl_exec($this->curl);

#UPDATE 1

After a debug I generated Verbose output from CURL execute. The first thing that I noticed is that on my remote file I can find this:

* skipping SSL peer certificate verification

but not in the local file. Maybe it is the reason why it doesn't work on remote?

#UPDATE 2

I printed on a file this json_encode(curl_getinfo($this->curl))) and I got two different results. Here details:

LOCAL DEBUG -- {\"url\":\"https:\\/\\/mysite.com\\/account\\/login\",\"content_type\":\"text\\/html; charset=UTF-8\",\"http_code\":403,\"header_size\":685,\"request_size\":1010,\"filetime\":-1,\"ssl_verify_result\":0,\"redirect_count\":0,\"total_time\":0.176508,\"namelookup_time\":0.000194,\"connect_time\":0.000213,\"pretransfer_time\":0.000894,\"size_upload\":112,\"size_download\":42170,\"speed_download\":239602,\"speed_upload\":636,\"download_content_length\":42170,\"upload_content_length\":112,\"starttransfer_time\":0.174651,\"redirect_time\":0,\"redirect_url\":\"\",\"primary_ip\":\"server_ip\",\"certinfo\":[],\"primary_port\":443,\"local_ip\":\"ip_of_my_local_computer\",\"local_port\":53952,\"http_version\":2,\"protocol\":2,\"ssl_verifyresult\":0,\"scheme\":\"HTTPS\",\"appconnect_time_us\":224,\"connect_time_us\":213,\"namelookup_time_us\":194,\"pretransfer_time_us\":894,\"redirect_time_us\":0,\"starttransfer_time_us\":174651,\"total_time_us\":176508}
REMOTE DEBUG -- {\"url\":\"https:\\/\\/mysite.com\\/account\\/login\",\"content_type\":\"text\\/html; charset=UTF-8\",\"http_code\":403,\"header_size\":685,\"request_size\":1010,\"filetime\":-1,\"ssl_verify_result\":0,\"redirect_count\":0,\"total_time\":0.125804,\"namelookup_time\":3.5e-5,\"connect_time\":3.7e-5,\"pretransfer_time\":0.000151,\"size_upload\":112,\"size_download\":42170,\"speed_download\":335203,\"speed_upload\":890,\"download_content_length\":42170,\"upload_content_length\":112,\"starttransfer_time\":0.125545,\"redirect_time\":0,\"redirect_url\":\"\",\"primary_ip\":\"server_ip\",\"certinfo\":[],\"primary_port\":443,\"local_ip\":\"ip_of_my_remote_server\",\"local_port\":39082}

As you can see, the first line (local server) I have some additional infos at the and of the line.

Thanks

Swim89
  • 290
  • 8
  • 28
  • 2
    "doesn't work" gives us no clues about the change of circumstances. What error / result do you get back? (If you haven't checked, then go and look. Your code certainly contains no curl error checking.) – ADyson Sep 07 '21 at 12:36
  • It is like the login was not performed and it go back to login form – Swim89 Sep 07 '21 at 20:11
  • 1
    Ok. Don't you have any more detail than that? Have you done any actual debugging? We can't run the code remember, so unless we can spot any obvious issues from what you've shown, then we're relying on you to give some clues by having actually investigated what the code is doing in depth. And especially since this code works in one environment but not another, than debugging info is even more important, since the code itself is less likely to have obvious mistakes in it. It's more likely to be something like a connection issue or similar. To reveal that, you have to gather errors etc. – ADyson Sep 07 '21 at 20:27
  • 1
    Maybe at least start by inspecting curl errors - see https://www.php.net/manual/en/function.curl-error.php – ADyson Sep 07 '21 at 20:29
  • @ADyson how can I debug it? Could you please suggest me which steps execute? – Swim89 Sep 12 '21 at 18:10
  • Well my second comment suggested one specific step already. But if you don't know how to debug in general, then see here: http://www.phpknowhow.com/basics/basic-debugging/ for a basic starter guide – ADyson Sep 12 '21 at 18:28
  • 1
    For cURL specifically then see https://stackoverflow.com/questions/3757071/php-debugging-curl (and others - just Google "PHP how to debug cURL" for plenty of information.) – ADyson Sep 12 '21 at 18:29
  • @ADyson thanks for your support. I generated verbose output from my cURL action and I updated my main post with details. Could you please help me to solve it? – Swim89 Sep 12 '21 at 18:53
  • That's more of a general log message than an error, doesn't really tell us much – ADyson Sep 13 '21 at 22:19
  • I don’t think it has an error problem. I think could be a timeout problem or a SSL Certificate problem. What do you think? – Swim89 Sep 13 '21 at 23:05
  • I don't know. You haven't provided any evidence of either of those things (or anything else either). – ADyson Sep 13 '21 at 23:14
  • Could be also a time-out problem? Which parameters on php configuration should I change to check it? – Swim89 Sep 18 '21 at 17:27
  • Have you tried getting the results of [curl_error](https://www.php.net/manual/en/function.curl-error.php) yet? – ADyson Sep 19 '21 at 07:31

0 Answers0