-
Notifications
You must be signed in to change notification settings - Fork 20.6k
jQuery.parseHTML: Mitigate XSS vulnerability #1505
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
Conversation
Scripts passed in event attributes are executed in `parseHTML` immediately, without any possibility for the user to intervene: `jQuery.parseHTML('<img src=x onerror=alert(1)>');` To mitigate this vulnerability `document.implementation.createHTMLDocument()` should be used as standard context instead of `document`. Now the user has to set a different context deliberately for this issue to occur. See also jQuery ticket #13921.
I like the sentiment behind this! I just put together some wording to clarify the problem at jquery/api.jquery.com@6137d67 but am not really happy about it. Do you know the range of browser support? It looks like this may be usable on all browsers that jQuery 2.x supports but not jQuery 1.x: http://stackoverflow.com/questions/18003264/document-implementation-createhtmldocument-browser-support Mainly I'd be worried about Android, especially Android 2.3. |
I'll modify this PR to check for support with jQuery.isFunction() first, falling back to |
I'm now checking for |
The current implementation relies on `document.implementation.createHTMLDocument`, which may not be available in older Android browsers (<= 2.x).
defaultContext = jQuery.isFunction( document.implementation.createHTMLDocument ) | ||
? document.implementation.createHTMLDocument() | ||
: document; | ||
/* jshint laxbreak: false */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our style guide calls for the ?
and :
at end of line (i.e., no laxbreak
).
This seems really nice, especially if we can drop the fallback in 2.x. Thanks, @fhemberger! |
See the comment here. |
See the comment here. |
Any news on this issue? Can it be merged in it's current state? |
@fhemberger This will go into 1.12/2.2 so we don't want to land it in master if a 1.11.1/2.1.1 is going to come out soon. We haven't forgotten about it though! |
@dmethvin Great, thanks. We're already working on a separate plug-in for strict security-related DOM filtering, which will work nicely together with this patch. |
A few remarks regarding the commit:
|
@@ -15,7 +15,10 @@ jQuery.parseHTML = function( data, context, keepScripts ) { | |||
keepScripts = context; | |||
context = false; | |||
} | |||
context = context || document; | |||
// document.implementation stops scripts or inline event handlers from being executed immediately | |||
context = context || ( jQuery.isFunction( document.implementation.createHTMLDocument ) ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of being run inline, this check should be executed once with the results captured as a support property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you already have a place in one of the files for those kind of checks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Several, actually.
This particular test could go in the base var/support.js, but if not then probably in a new core/support.js similar to manipulation/support.js.
I have a slight preference for the former, but would opt for the latter if it meant a smaller gzipped output file.
Since getter was removed in fdd78fa there is no longer a need to wrap option element in order to get its value Fixes #14756
More to come later. (cherry picked from commit f6f8848)
Thanks to @TheDistantSea for the report! Fixes gh-1790 Closes gh-1643
Some environments do not support data-uri in "src" attribute of script element. Mitigate it with equality assertion Ref a467f86
Waaah! Rebasing from master added all commits … relevant is only 6a4672c. If you want, I can send a new, clean PR which should be easier to merge. |
You probably didn't rebase but merge it.
That might be the best way to do it |
You could also |
Unfortunately, we had to back it out for now because of Safari 8 bugs: b779831. |
This is the related WebKit bug report: https://bugs.webkit.org/show_bug.cgi?id=137337 |
Thanks a lot for finding it! This seems hard to patch on our side (at least without adding a lot of code) and using What do you all think? Judging by the fact that the bug is still open I don't see a quick solution on Safari side. |
Well, you could detect this specific bug using the code of the test case: var doc = document.implementation.createHTMLDocument('');
var bodyEl = doc.documentElement.lastChild;
bodyEl.innerHTML = '<form></form><form></form>';
var isSafariBug = (bodyEl.childElementCount === 1); Add this check to the general |
Oh 💩. Well, here for the second time in a week we are faced with a crippling Safari bug and no way to know what Apple may decide what to do. How about feature-detect this similar to what @fhemberger describes and skip using the technique in Safari as a result? Then we can simply warn people that using Safari is less safe. |
Yes, I think that's the best way to deal with this right now … then the changes of this PR could be backported 1:1 for the 1.x branch (as we don't have any fallback there for IE8 as well). |
The document.implementation.createHTMLDocument("") method creates inert documents which is good but using it has introduced issues around anchor elements href property not resolving according to the current document. Because of that, this patch is getting backed out on 1.x/2.x branches. Refs cfe468f Refs gh-1505 Fixes gh-2941
This was originally backported to 1.12/2.2 but due to #2941 we're backing out the patch on those branches (as they wen't meant to be non-breaking releases and there may always be more issues around that); we'll try to fix the issue for 3.0. |
The document.implementation.createHTMLDocument("") method creates inert documents which is good but using it has introduced issues around anchor elements href property not resolving according to the current document. Because of that, this patch is getting backed out on 1.x/2.x branches. (cherry-picked from c5c3073) Refs cfe468f Refs gh-1505 Fixes gh-2941
Scripts passed in event attributes are executed in
parseHTML
immediately,without any possibility for the user to intervene:
jQuery.parseHTML('<img src=x onerror=alert(1)>');
To mitigate this vulnerability
document.implementation.createHTMLDocument()
should be used as standard context instead of
document
. Now the user hasto set a different context deliberately for this issue to occur.
See also jQuery ticket #13921.
EDIT: Agreed to the CLA.