2

I want to simulate login with curl in php with csrf token. I know the token is refreshed every session and I need to use the same cookie and I do it like this:

<?php 

use Symfony\Component\DomCrawler\Crawler;

require 'vendor/autoload.php';

function login($url,$data){
    $login = curl_init();
    curl_setopt($login, CURLOPT_COOKIEJAR, "cookie.txt");
    curl_setopt($login, CURLOPT_COOKIEFILE, "cookie.txt");
    curl_setopt($login, CURLOPT_TIMEOUT, 40000);
    curl_setopt($login, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($login, CURLOPT_URL, $url);
    curl_setopt($login, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($login, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($login, CURLOPT_POST, TRUE);
    curl_setopt($login, CURLOPT_POSTFIELDS, $data);
    ob_start();
    return curl_exec ($login);
    ob_end_clean();
    curl_close ($login);
    unset($login);    
}                  

function grab_page($site){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($ch, CURLOPT_TIMEOUT, 40);
    curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
    curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
    curl_setopt($ch, CURLOPT_URL, $site);
    ob_start();
    return curl_exec ($ch);
    ob_end_clean();
    curl_close ($ch);
}

// Grab the page with the csrf_token
$signinPage = grab_page('https://bitbucket.org/account/signin/');

$crawler = new Crawler($signinPage);

$csrf = $crawler->filter('input[name=csrfmiddlewaretoken]')->first();

$csrf = $csrf->attr('value');

login('https://bitbucket.org/account/signin/', ['next' => '', 'csrfmiddlewaretoken' => $csrf, 'username' => 'myemail', 'password' => 'mypass']);

var_dump(grab_page("https://bitbucket.org/site/oauth2/authorize?client_id=my_client_id&response_type=code"));

But it still does not login correctly. Where am I wrong ?

Angel Miladinov
  • 1,596
  • 4
  • 20
  • 43
  • 1
    Any code after the `return` will not run by the way – apokryfos Apr 03 '18 at 08:27
  • I thought the whole point of CSRF tokens is that you cannot pass login details like this... Unless you have that secret key you will not be able to make a successful login as that token changes every request. Can't you use the actual API provided by [atlassian](https://developer.atlassian.com/bitbucket/api/2/reference/)? – IsThisJavascript Apr 03 '18 at 08:30
  • @IsThisJavascript that's not the point of CSRF tokens. You're thinking of a nonce – apokryfos Apr 03 '18 at 08:31
  • Is there maybe a request header involved that you need to send? – Gabor Lengyel Apr 03 '18 at 08:32
  • Does the crawler actually find anything in the `$csrf` variable? – apokryfos Apr 03 '18 at 08:32
  • @apokryfos yes I checked it. It returns the csrf correctly – Angel Miladinov Apr 03 '18 at 08:34
  • @IsThisJavascript I am doing this so I can use their api. I know how to use it once I have the access token, but I want to automize the getting of the access token so you don't need to enter in this url manually everytime and get it from there. – Angel Miladinov Apr 03 '18 at 08:35
  • @TheAngelM97 I don't know the BitBucket API, but I'm pretty sure this is not the recommended way to get a token. :) – Gabor Lengyel Apr 03 '18 at 08:36
  • You posting form data to wrong site, take a look to source code an you'll see that the action is set to: `/socialauth/login/google-oauth2/` – Kazz Apr 03 '18 at 08:37
  • 1
    @TheAngelM97 you should not do this to get an oauth token. Read up on https://tools.ietf.org/html/rfc6750 on how to get a token (or use an oauth2 library) – apokryfos Apr 03 '18 at 08:40

0 Answers0