1

I have a script that downloads and displays an web page from an external site. The site generates a one-time token and stores it in a hidden form field, and puts the same token in the cookie it sends to the user. In my first cURL request, I store the cookie:

$url = 'http://www.example.com/form.php';
$host = parse_url($url, PHP_URL_HOST);
$referer = 'http://' . $host;
$ip_address = $_SERVER['REMOTE_ADDR'];

// Give the user a unique cookie file for each request
$cookie_file = 'cookies/' . sha1($ip_address . $agent . $url) . '.txt';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPGET, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIESESSION, false);

$file = curl_exec($ch);

This works fine and it correctly creates the cookie file, and when I open it up, it has the one-time token in it, and it matches the token in the hidden form field.

When I submit the form, I make another cURL request, using the same cookie:

$ch = curl_init($url);

$postdata = http_build_query($postdata);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
$ip_address = $_SERVER['REMOTE_ADDR'];
$cookie_file = 'cookies/' . sha1($ip_address . $agent . $url) . '.txt';
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($ch);

The cookie file name should be the same the second time around, since the user's ip, agent, and target original url haven't changed. I've verified that it doesn't create a second cookie for the request and doesn't overwrite the first one.

But when I submit the form, the CSRF validation fails, even though I didn't change the hidden form field, and it matches the one-time token in the cookie, and I set the HTTP referer to the target url. Is there some other reason why the CSRF check would fail? Is it not using the cookie in the second request for some reason? Any help is appreciated, thanks :)

Joey
  • 10,504
  • 16
  • 39
  • 54

1 Answers1

0

You might have to redefine your variables. Your $agent and $url are not there in seconds cURL request.

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
  • They are there because I pass them there. If they weren't, it would generate a new cookie because the name would be different. – Joey Mar 17 '12 at 20:09