is putting token in URL secure to prevent CSRF attacks in PHP applications?

14,717

Solution 1

Yes, if the CSRF token is 'unguessable' and validated: the approach is the same in both cases.

From Wikipedia's Cross-site Request Forgery - Prevention:

Web sites have various CSRF countermeasures available .. Requiring a secret, user-specific token in all form submissions and side-effect URLs prevents CSRF; the attacker's site cannot put the right token in its submissions.

It doesn't matter if the token is from a form value or a query string parameter1. An approach that prevents CSRF by including a token in forms is adaptable to (and valid for) hyperlinks2.


1 A MitM / proxy which can intercept a URL can just as easily intercept an HTML form. This is outside the scope of a standard CSRF attack or mitigiation of such. In such cases the CSRF token value is 'knowable' and system is not secure.

2 This assumes the token is a per-user (and time-sensitive) value. A simple HMAC hash of the Session ID should be sufficient in most cases.

Solution 2

I think one of main disadvantages of using CSRF-token in GET requests is possibility of incompetent user to easily disclose his token by copying a link with the token and paste it in some public content like a comment/post/etc... Also GET query parameters including CSRF-tokens usually logged by HTTP servers/proxies and it introduces another risk.

So I suggest you to implement CSRF-secure links using something like this:

<form name="logout" action="logout.php" method="post">
<input type="hidden" name="token" value="9ae328eea8a72172a2426131a6a41adb"/>
</form>
...
<a href="/nojs.html" onclick="document.logout.submit(); return false">Logout</a>
Share:
14,717
Mohammad Saberi
Author by

Mohammad Saberi

Updated on June 18, 2022

Comments

  • Mohammad Saberi
    Mohammad Saberi almost 2 years

    I want to use a token to prevent CSRF attacks on my website (written with PHP). I've used it in forms and it works well. But logout link is not a form; It is only a hyperlink.
    Is it secure if I put the token in the query string like this:

    <a href="logout.php?token=9ae328eea8a72172a2426131a6a41adb">Logout</a>
    

    If it has any problem, what is your suggestions and solutions ?

  • user2864740
    user2864740 almost 10 years
    While a valid point, a valid CSRF token to should trivial be tied to the session (but should not be the session key itself - a HMAC hash is usually suitable): even an accidental exposure of such a token should have a minimum time-of-vulnerability (i.e. maximum of session lifetime). Also, since the CSRF requires self-initiation, it will only be effective is the user can be convinced to run the "side-effect URL" (with different parameters that perform a "bad" action); others with access to just the URL would still not be able to access the session or bypass the site authentication.
  • user2864740
    user2864740 almost 10 years
    That is, I see no inherent reason not to use an appropriate CSRF token in a URL.
  • Mohammad Saberi
    Mohammad Saberi almost 10 years
    Thank you for your answer. But what is your idea about what mentioned in owasp.org/index.php/… page? (Disclosure of Token in URL)
  • user2864740
    user2864740 almost 10 years
    @MohammadSaberi That article assumes a problem based on "..the unique per-session token is being exposed for GET requests" (I would argue this should be done, even for POST). This is why the Session ID should HMAC hashed - so the "per-session token" is not disclosed. Using an HMAC can also incorporate/impose a sub-session lifetime on the token validity.
  • user2864740
    user2864740 almost 10 years
    @MohammadSaberi However, it does raise a good point wrt. non-idempotent actions and GET: "If sensitive [side-effect] server-side actions are guaranteed to only ever respond to POST requests, then there is no need to include the token in GET requests." - That is, it may be more appropriate/correct to use a form POST action (and not a hyperlink/GET) to initiate the side-effect/non-idempotent action. (And buttons can be styled to look like hyperlinks with CSS.)
  • dened
    dened almost 10 years
    Shortening lifetime of CSRF-token too much will introduce problems with usability (not working CSRF-secure links/buttons after short timeout), so attacker usually have more time than enough. And regarding the second objection, I can remind you that CSRF attack is all about "convincing user to run the side-effect URL". ;)
  • user2864740
    user2864740 almost 10 years
    While I would use a button and CSS (not an anchor and JS), I upvoted this answer because of the of POST (not the form, although that falls in as a result) to invoke the side-effect action.
  • dened
    dened almost 10 years
    Do you prefer styling native submit button over <a> because it don't require javascript? It is good point, but it should be noted that <form> is not allowed everywhere in HTML where <a> is. For example, HTML standard don't allow you to put two <form>s on single paragraph, but you can put as many <a> there as you like and use them to submit forms with help of javascript.
  • Awaaaaarghhh
    Awaaaaarghhh about 4 years
    i don't understand the connection between your answer and the question. question was actually not about implementation but about using cstf-token in urls. nice answer but a bit out of place.
  • Awaaaaarghhh
    Awaaaaarghhh about 4 years
    users posting url with csrf token is a valid argument. have seen it often enough.