justinas/nosurf

Validation fails with X-CSRF-Token

danjac opened this issue · 8 comments

I'm only able to get a 400 Bad Request with POST/DELETE requests to my REST application.

Running an app in localhost I have this value in my csrf_token cookie:
0bYcWmFvvMpZXMSgau2Jx3uxQGhyfEtTxOEC6zrtlfs=

And the value passed back in X-CSRF-Token:
0bYcWmFvvMpZXMSgau2Jx3uxQGhyfEtTxOEC6zrtlfs=

My set up:

http.Handle("/", nosurf.New(myRoutes))
http.ListenAndServe(":"+port, nil)

I had this working fine until a recent go get update, so some kind of regression maybe?

In later versions, tokens should not match up exactly, as they're masked per-request. While the move to masked tokens was supposed to be seamless, that might have been a wrong assumption on my part (tokens might not regenerate as needed).

Try regenerating the token. When working correctly, the form/header token should be two times longer than the one in the cookie.

I'll issue a fix for this soon, for now, just regenerating by hand should work.

I tried regenerating the token, clearing cookies, different browsers etc with the same result.

Works fine for me (using simple.go example and jQuery to POST). Like I've mentioned, the token you send should be twice as long compared to the token in the cookie.

If you're trying to submit the very same token from the cookie, don't. Use nosurf.Token(r) instead to get a token to submit.

Did that solve your issue?

I wanted to avoid using POST each time, in order to integrate with
AngularJS CSRF header/cookie settings - so ended up rolling my own (over
xsrftoken) instead.

On 28 May 2014 15:34, Justinas Stankevičius notifications@github.comwrote:

Did that solve your issue?


Reply to this email directly or view it on GitHubhttps://github.com//issues/7#issuecomment-44400152
.

yktoo commented

Well, apparently this is not going to work with Angular as it sends back in the Header exactly what it collected from the cookie.

I'm actually missing the point of modifying the token on each request, and so are the Angular authors apparently. The fact the token can only be generated on the backend makes it, sadly, a no-go for AJAX apps. Unless I'm overlooking something here.

Well, apparently this is not going to work with Angular as it sends back in the Header exactly what it collected from the cookie.

Is this some built-in functionality of Angular? I am afraid we can not adjust to every framework's way of doing things. However, in general this is a solved issue, and other frameworks recommend doing a similar thing:

<script>
window.csrfToken = "{{ .Token }}";
</script>

in your Go template, then use it as necessary. You should be able to re-submit the same token multiple times.

yktoo commented

Thanks a bunch for your advice!

Yes, it is the standard behaviour of Angular, so one will need to alter that flow to collect the token from a variable and add it as a header.