Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSFR tokens for multiple forms\post per page (Ajax) #59

Closed
mhdcodes opened this issue May 24, 2016 · 11 comments
Closed

CSFR tokens for multiple forms\post per page (Ajax) #59

mhdcodes opened this issue May 24, 2016 · 11 comments

Comments

@mhdcodes
Copy link

I have a Page that dynamically loads multiple forms via ajax let say each form is supposed to be a like button,

so when CSFR is disabled forms works fine , and no exception is thrown ,but when enabled the problem appear
the problem is the first request will work because the tokens will match
but since ajax will not refresh the page the other forms will still have the old token so any subsquent request will not work and "Failed CSRF check!" exception will be thrown ,
i searched a lot for a solution and i find a tedious one which is to return the new csrf in the response to the AJAX post, then update the value of the csrf token field but it is not a fancy soulotion besides im using a CSRF middleware to append the values automaticly

` public function __invoke($request, $response, $next){

    $nameKey = $this->container->csrf->getTokenNameKey();
    $valueKey = $this->container->csrf->getTokenValueKey();

    $name = $this->container->csrf->getTokenName();
    $value = $this->container->csrf->getTokenValue();

    // Render HTML form which POSTs to /bar with two hidden input fields for the
    // name and value:
    $output  = '<input type="hidden" name="'.$nameKey .'" value="'.$name .'">';
    $output .= '<input type="hidden" name="'.$valueKey.'" value="'.$value.'">';

    // Append The CSRF Gards To The View
    $this->container->view->addAttribute('csrf_gards', $output );

    // Pass the Request to the next one
    $response = $next($request, $response);
    return $response;
}`

a nice approach like CodeIgniter would be to allow this kind of behavior
$config['csrf_regenerate'] = FALSE;

so any help would be appreciated

@X-Tender
Copy link

I just ran into the same problem, currentl I just disable the lines in the Middleware which remove the token and generate a new one :/

@chrisemerson
Copy link

I'm having this issue at the moment. It seems that a lot of libraries that provide CSRF protection simply check for the presence of the X-Requested-With header in the request, which can't be faked through a CSRF attack (HTML forms are unable to set this), so also provides CSRF protection.

Is there any scope here for expanding this library and getting the middleware to let requests through that have the X-Requested-With header present, even if the tokens are present / incorrect?

I am currently sending back new tokens with each AJAX request made, but this has the disadvantage that you can only make 1 request at a time. For something making a few AJAX requests at once, this method is impossible currently.

@schnittstabil
Copy link
Contributor

check for the presence of the X-Requested-With header in the request, which can't be faked through a CSRF attack (HTML forms are unable to set this)

Dunno if this still applies, but X-Requested-With can be faked by Flash.

@chrisemerson
Copy link

Cross domain?

@schnittstabil
Copy link
Contributor

Cross domain?

Cross-Site Request Forgery – Hence, yes cross domain.

Maybe these Flash plugins are outdated, but relying only on the existence of an header filed is insecure. See the flash's header blacklist – but I'm not a flash developer…

Furthermore it is not only about all the countless browsers, there are also apps, standalone IoT clients, plugins etc.

@chrisemerson
Copy link

So what's the solution for allowing concurrent AJAX requests then?

@schnittstabil
Copy link
Contributor

schnittstabil commented Oct 23, 2016

  • One single token per session, which is currently discussed at Slight quibble about implementation #49.
  • Or you may want to switch to some crypto solution, e.g. signed header tokens like JWT with an exp (expiration time) claim, protect against **non‑**anonymous(!) CSRF attacks.

However, both solutions are vulnerable to replay attacks within the session and expiration time respectively, at least in some edge cases.

@chrisemerson
Copy link

I wonder what the risk levels of the flash attack compared to the replay attacks possible with the token per session are like.

@schnittstabil
Copy link
Contributor

I think, with https, replay attacks are almost impossible.

@rodrigogalura
Copy link

Try my solution

csrf-code

csrf-output

@abdo-host
Copy link

can you attach code ? @Rodz3rd2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants