1

I few months ago, my colleague created an calendar subscription by getting the work schedule. I believe he has done this by cURL.

Now I'm building a website to have an overview about the tasks that should be done today.

I want to retrieve the schedule so I can use it to display the name of the people that are working a specific day.

I found a tutorial on the web that explains how I can get de data after a login. what I did is that I copied the name of the input fields in the login form, and the name of a hidden field named signin[_csrf_token]

with those names, I created the following code:

<?php

$username = "myusername";
$password = "mypassword";
$url = "http://planner.a-mac.nl/employeeSchedule";
$cookie= "koekje.txt";
$token = "2e4c16f2b664f3ed01827dd38dc11d22";
$ch = curl_init();


                        curl_setopt($ch, CURLOPT_POST, true);
                        curl_setopt($ch, CURLOPT_URL, $url);
                        curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/'.$cookie);
                        curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/'.$cookie);


                        curl_setopt($ch, CURLOPT_POSTFIELDS, "signin[username]=" . $username ."&signin[password]=" . $password . "&signin[_csrf_token]=" . $token);
                        //stuur de gegevens uit het formulier door naar de link

                        curl_exec($ch);
                        //Zet de output op het scherm

                        if (curl_errno($ch))
                            {
                                   print curl_error($ch);
                                   //Als er een fout is geef deze dan
                            }
                        else
                            {
                                curl_close($ch);
                                //Sluit de link met de website
                            }
?>

When I load my page with the above code, I get the login form with the error message:

CSRF Attack Detected

Could someone help me how to solve this problem so I can what data I got from the website?

I contacted my old colleague, but he says "he doesn't know anymore"...

Jules
  • 546
  • 2
  • 11
  • 36
  • Never build POST data string manually. There is special function for this purpose: `http_build_query` – hindmost Feb 28 '15 at 19:18

3 Answers3

8

The CSRF token field value is not fixed but is a randomly generated value for newly created sessions. You need a "clean" call to the webpage first to obtain a CSRF token value, only after that you can POST the username/password together with the CSRF token, as in:

<?php

  $username = "myusername";
  $password = "mypassword";
  $url = "http://planner.a-mac.nl/employeeSchedule";
  $cookie= "koekje.txt";
  $ch = curl_init();

  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/'.$cookie);
  curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/'.$cookie);

  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $response = curl_exec($ch);
  if (curl_errno($ch)) die(curl_error($ch));

  $doc = new DOMDocument();
  $doc->loadHTML($response);
  $token = $doc->getElementById("signin__csrf_token")->attributes->getNamedItem("value")->value;

  curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
  curl_setopt($ch, CURLOPT_POST, true);

  $params = array(
    'signin[username]' => $username,
    'signin[password]' => $password,
    'signin[_csrf_token]' => $token
  );
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));

  curl_exec($ch);

  if (curl_errno($ch)) print curl_error($ch);
  curl_close($ch);
?>
Hans Z.
  • 50,496
  • 12
  • 102
  • 115
  • I keep getting the error message "csrf token: Required" ?? The hidden input field in the login form has the id signing__csrf_token ... – Jules Feb 28 '15 at 19:30
  • added the complete code now; this (obviously) renders to `The username and/or password is invalid.` instead for me instead of the previous `csrf token: Required` – Hans Z. Feb 28 '15 at 19:50
  • Strange this is, when I change the $url to the login screen, I get redirected to the site, when I change the url to ../login or ../employeeSchedule I see a blank page, Do you have any idea what is going wrong? – Jules Mar 02 '15 at 09:40
2

The idea behind CSRF defense is based around generating a unique token for each page load which you have to pass with the form.

You will have to load the page with the form, extract the token from the page and pass that along with the POST request. Typically, after any attempt, the token is invalidated and you must request the form again to get a new token.

The CSRF token is stored in the session, so the server can see if the one generated on the form matches the one supplied with the request sending the form.

vvondra
  • 3,022
  • 1
  • 21
  • 34
0

I have a feeling that you should be adding the token like this:

$headers[] = 'X-CSRF-Token:' .  $token;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
albertski
  • 2,428
  • 1
  • 25
  • 44
  • My problem has been solved by contacting an administrator so I could have access to the database. I'm using data directly from the database now but thanks for your suggestion! – Jules May 01 '15 at 14:06