A Friend
A Friend

Reputation: 1476

CSRF only needed for ajax

I have recently been working with a way to stop CSRF attacks happening by using a token. To my understanding:

1) User logs in, set session cookie to logged in and generate CSRF token and save it to the session

2) User submits form (with token) and it should match the token in session

Hypothetically lets say I have page1.php which has a sql SELECT to get all the users account information and then within the same page I also have an ajax button to page2.php which changes the account information. Obviously I protect page2.php from CSRF (because this is a post request) but how do I protect against page1.php? If this page was to get called from a remote source by ajax or putting an iframe on an attackers website, surely this would print all of the victims account information?

If this is the case how come I can't seem to find anything on protecting all pages from CSRF attacks and I only find resources for protecting against CSRF attacks in ajax?

Upvotes: 1

Views: 621

Answers (3)

user3277192
user3277192

Reputation:

Hypothetically lets say the page has a sql select on it and does not request post. Now if this page was to get called from a remote source by ajax or putting an iframe on their website, surely this would print all of the victims data?

Make sure that all requests that hand out "confidential" information (either as a webpage or as data for an ajax call (or whatever in the future) do validate that there is a valid session active. If it's not, make sure the server side portion does not hand out anything confidential but instead throw an error and make sure your ajax client understands it and does the right thing for normal users (like telling them they're not logged in and offering them to fix that).

If this is the case how come I can't seem to find anything on protecting all pages from CSRF attacks and I only find resources for protecting against CSRF attacks in ajax?

For regular post requests typically the form is output with a hidden input field that holds the CSRF token. That's all.

BUT do make sure the code processing the request validates that the hidden field is present and filled in with the right value.

Also make sure that any request that modifies things is CSRF protected. E.g. that delete button in a non-ajax context should be protected with sending and validation of the CSRF token (hence the button ends up as a form with a hidden field for the CSRF.

Upvotes: 0

Gabor Lengyel
Gabor Lengyel

Reputation: 15570

Suppose you have a page at http://application.com/mypage with some data and a CSRF token generated. Attacker creates http://attacker.com/attack, and when a valid user of application.com visits, makes a request (either via ajax or in an iframe, doesn't matter) to application.com in order to get hold of application data. Standard csrf.

The reason this won't work for the attacker is the same origin policy. When the victim user is on attacker.com, the request to application.com will be cross-domain. If it's an iframe, data will be displayed, but attacker.com will have no access to it, it will only be displayed for the user that could have a look on application.com anyway. If it's an ajax call, the same applies, javascript on attacker.com will have no access to the response, ensured by the browser.

For ajax calls, access to cross-domain responses can be explicitly enabled by the access-control-allow-origin and related response headers (CORS) sent by application.com in the response.

Note that despite being cross-domain, the call will still be made (preflight requests come into play in some cases, but let's not go into that now). It's only the response that will be inaccessible for the attacker, and that is enough to prevent csrf.

(Also as a sidenote, application.com should prevent being displayed in an iframe by for example sending an x-frame-options: sameorigin header to prevent clickjacking and similar attacks, but that was not the question.)

Upvotes: 1

Juan
Juan

Reputation: 5589

I am not sure I get the point but the token for CSRF should be a nonce, which changes on each call.

Regarding a call coming from some other place, the ajax request should also check that the call comes from a valid user with the correct entitlments as you would do with any "regular" call to the site.

If this is the case how come I can't seem to find anything on protecting all pages from CSRF attacks and I only find resources for protecting against CSRF attacks in ajax?

What you ussually do is to set a nonce in a hidden input of the forms you use in "regular" pages.

Upvotes: 0

Related Questions