CSRF protection from cross-origin <script> tags#13345
Conversation
There was a problem hiding this comment.
This content type comparison is gross but I couldn't find a better alternative.
There was a problem hiding this comment.
Can content type be some other like application/javascript?
There was a problem hiding this comment.
text/ecmascript and application/ecmascript are also valid values and I think there are more supported content types for javascript execution.
Whitelisting is not an option right?
There was a problem hiding this comment.
unless I'm mistaken, doesn't the Mime types already take care of this?
request.format == :js && !request.xhr?
There was a problem hiding this comment.
@pothibo request.format is the requested format, not the response Content-Type.
For example, in #test_should_only_allow_same_origin_js_get_with_xhr_header:
> [content_type, request.format, rendered_format]
=> ["text/javascript", #<Mime::Type:0x007ff4d96d15e8 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">, #<Mime::NullType:0x007ff4d8438530>]There was a problem hiding this comment.
@rafaelfranca You'll only get those Content-Type if you manually specify them with render ..., type: 'application/ecmascript'. Mime::JS will always be text/javascript.
We may want a whitelist to extend verification to other Content-Type (including JSON for those supporting ancient browsers) in the future, but I don't think it's necessary to start.
|
👍 Thanks! |
There was a problem hiding this comment.
If people can skip verify_authenticity_token in a controller that inherits protect_from_forgery, then mark_for_same_origin_verification would still be triggered and thus verify_same_origin_request too, not? Would they need to skip that too, independently?
There was a problem hiding this comment.
Yes. I'll move the marker to verify_authenticity_token to fix that.
I used a separate, private method because we encourage people to change the builtin method:
# The actual before_action that is used. Modify this to change how you handle unverified requests.
def verify_authenticity_tokenSo an overriding method would miss the marking and skip same-origin verification.
I'm removing that comment. Shouldn't be overriding that method.
|
Tests are broken 😢 |
actionpack/CHANGELOG.md
Outdated
There was a problem hiding this comment.
Extend protect_from_forgery to GET requests with JavaScript responses,
Thanks to @homakov for sounding the alarm about JSONP-style data leaking
|
@rafaelfranca fixed the other broken tests, they hit the same-origin verification 😁 |
|
|
|
👍 |
CSRF protection from cross-origin <script> tags
|
@jeremy probably instead of exception it should respond with "please send x requested with header to verify request origin" |
|
@homakov thought about that.. responding with 403 Forbidden so it's clear it's a client error not an application error App devs can use In any case, this is starting as small as possible. I hope we'll see PRs that do a default |
|
@TechFounder Sounds like you're making a GET request that has a JavaScript response, but you aren't passing the |
|
In our production server i'm getting Am i seeing these inconsistencies because of browser differences? I'm using |
|
@harmdewit did you ever figure this out? I'm having the same issue. |
|
I'm not sure what the issue was after this long time but putting this into our ApplicationController seemed to fix it + def non_xhr_javascript_response?
+ unless request.get?
+ content_type =~ %r(\Atext/javascript) && !request.xhr?
+ end
+ end |
|
Thanks @harmdewit! 😃 |
|
I'm not sure what is requesting format=/ either. Another solution I came up with is to reorder the So I changed this: respond_to do |format|
format.js do
...
end
format.html
endto this: respond_to do |format|
format.html
format.js do
...
end
endThat way format=/ will return html. |
rails/rails#13345 introduced CSRF protection to gets with JavaScript responses.
rails/rails#13345 introduced CSRF protection to gets with JavaScript responses.
Extend
protect_from_forgeryto cover GET requests with JavaScript responses, protecting apps from cross-origin<script>embedding that may leak sensitive data.TODO
Acceptrather than an explicit formatAccept