[99s-extend] Reading body_qs multiple times

Loïc Hoguin essen at ninenines.eu
Tue Apr 16 13:34:14 CEST 2013


On 04/16/2013 02:13 AM, rambocoder wrote:
> Loic,
>
> After giving the CSRF middleware some thought and reading
> https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Disclosure_of_Token_in_URL I
> came to conclusion that it is best to just not create the middleware and
> instead deal with CSRF on as needed basis.

Your link says what I said too, except I probably wasn't explicit enough.

If you have a form that does POST (or PUT or PATCH or DELETE), put the 
token in "<form action="/path/to/resource?csrf=$TOKEN">". The token must 
be only valid once, it must not be reused, not even between different 
forms (each form gets its own token). Since it is not a GET request, 
then you don't have cache or referer issues.

You can still have issues if you allow another site to run JS on yours 
(but you probably shouldn't) or if there is a malevolent proxy (use SSL 
where needed), but these are different issues entirely.

> Btw, I noticed that when the result of the middleware execute function is:
> {error, StatusCode, Req}
> if I set the reply on the request via cowboy_req:reply before returning
> the {error.. , the status code of that reply will be used.
>
> Such as:
> {ok, Req3} = cowboy_req:reply(403, [], "Invalid CSRF Token.", Req2),
> {error, 500, Req3}; % 500 is ignored, 403 is returned

Yes, the response was already sent, therefore the second one is ignored.

> Is that by design?
>
> Sincerely,
>
> rambocoder
>
>
>
> On Mon, Apr 15, 2013 at 4:47 PM, Loïc Hoguin <essen at ninenines.eu
> <mailto:essen at ninenines.eu>> wrote:
>
>     Why not just put the token in the URL instead? if it's CSRF then
>     it's probably used only once and only for POST and the like, so not
>     cached or anything.
>
>
>     On 04/15/2013 10:45 PM, rambocoder wrote:
>
>         Hello group,
>
>         I am trying to put together a CSRF middleware
>         https://github.com/rambocoder/__stable/commit/__b26980d292ac42aadfe9921a961436__e28cdbb693
>         <https://github.com/rambocoder/stable/commit/b26980d292ac42aadfe9921a961436e28cdbb693>
>         and
>         if the body of the request contains "_csrf" token, I check to
>         make sure
>         it matches the csrf token in the session.
>
>         Currently I am doing it in middleware using cowboy_req:body_qs/1
>         however
>         when in the handler I need to read another body parameter, such
>         as in
>         the rest_pastebin example:
>
>         {ok, BodyQs, Req3} = cowboy_req:body_qs(Req),
>         Paste = proplists:get_value(<<"paste">__>, BodyQs),
>
>         cowboy_req:body_qs/1 returns [] due to the body of the request being
>         already read {body_state,done}
>
>         Is it pointless to have the type of CSRF middleware that I am
>         writing
>         and just do the CSRF in the handler's callback, where I can deal
>         with
>         all the body_qs at once?
>
>         Thank you,
>
>         rambocoder
>
>
>         _________________________________________________
>         Extend mailing list
>         Extend at lists.ninenines.eu <mailto:Extend at lists.ninenines.eu>
>         http://lists.ninenines.eu:81/__listinfo/extend
>         <http://lists.ninenines.eu:81/listinfo/extend>
>
>
>
>     --
>     Loďc Hoguin
>     Erlang Cowboy
>     Nine Nines
>     http://ninenines.eu
>
>


-- 
Loïc Hoguin
Erlang Cowboy
Nine Nines
http://ninenines.eu



More information about the Extend mailing list