- Notifications
You must be signed in to change notification settings - Fork20.6k
jQuery.parseHTML: Disable inline event handlers when removing scripts#1508
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
When removing script tags from the parsed result, inline event handlers shouldbe removed as well. It would be very insecure to create a blacklist ofevent handler attributes, in case of one being forgotten or new handlersbeing added in the future.Therefore, all attributes starting with `on*` should be replaced by a dataattribute of the same name. All code which might exist can still be accessed,but is not executed after being injected into the DOM to avoid possible XSSattacks.See also PR#1505.
This PR should be applied to |
@@ -17,6 +17,11 @@ jQuery.parseHTML = function( data, context, keepScripts ) { | |||
} | |||
context = context || document; | |||
// Disable event handlers like onload, onerror, etc. when scripts are removed | |||
if ( !keepScripts ) { | |||
data = data.replace( /\b(on[a-z]+)/gi, "data-$1" ); |
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.
This will fail on input like"<img src='/path/to/src' onload='finished(this)' data-onload='true'/>"
(attribute collision) or"Example vulnerability: <pre><img onerror='alert(\"Pwned!\")'/></pre>"
(content alteration). I think consistency trumps security here, and we have to reject this approach.
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.
Ok, I understand your first point, but the second example (content alteration) is desired in this case, disabling the XSS vector. This alteration doesn't differ much from removing<script>alert(1)</script>
whenkeepScripts
is not passed. As I've explained in the commit message, I don't see a safe and future-proof way to remove the event handler entirely.
So maybe a different valid prefix would be a middle ground we could agree on?
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.
No, I meant that in the sense of altering elementcontent instead ofattributes (which is certainlynot desired). The difference is substantial: imagine the effects of this PR on$el.html( "Example vulnerability: <pre><img onerror='alert(\"Pwned!\")'/></pre>" )
.
So maybe a different valid prefix would be a middle ground we could agree on?
There's no prefix that can both produce valid output and avoid attribute collision in all cases, but the value ofjQuery.expando
is close enough that we could safely pretend. However, even disregarding the above issue (which I'm not prepared to do), there's still either a) the unrequested alteration of input, or b) the performance hit of revisiting newly-created elements to undo it, neither of which I like.
Personally, I prefer encouraging everyone to sanitize user input before passing it to jQuery as HTML (or better yet—not doing so) over paying the size/performance/complexity/maintenance costs of trying to solve every edge case ourselves.
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.
Ah, now I got you. Ok, this might indeed be an unwanted side effect.
I don't think any regex can really fix this. It would be possible to try and sanitize the HTML if it were first parsed per the earlier PRs, but that is most likely a lot of code and should be done in a plugin. There's a pretty good list of "dangerous" stuff athttp://msdn.microsoft.com/en-us/library/windows/apps/hh465388.aspx |
When removing script tags from the parsed result, inline event handlers should
be removed as well. It would be very insecure to create a blacklist of
event handler attributes, in case of one being forgotten or new handlers
being added in the future.
Therefore, all attributes starting with
on*
should be replaced by a dataattribute of the same name. All code which might exist can still be accessed,
but is not executed after being injected into the DOM to avoid possible XSS
attacks.
See also PR#1505.