-
Notifications
You must be signed in to change notification settings - Fork 47.4k
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
Dangerous strings can reach browser builtins #12441
Comments
Some past discussion on this: |
If you're looking for safe HTML parsing and XSS protection, I offer up /~https://github.com/milesj/interweave (it's been pen tested). Ignore the failed build, I'm working on changing the environment. |
@gaearon Thanks for the pointers. To summarize, // explicitly React.createElement the POJO
<div>{trust(stringOrElement)}</div> This is similar to Perl untaint. Like tainting, it's a binary decision, not a decision to trust in a specific set of contexts a la /~https://github.com/WICG/trusted-types Other themes in that thread:
To respond in particular to the ones you mentioned:
Requiring values that are not simple numbers or keywords to be explicitly wrapped in a type that specifies them as such makes things easier. There is an ambiguity between strings used e.g., as URLs and font-faces which is problematic,
Agreed x 2.
This is true, but Webcomponents frameworks complicate things. In The same is not true when the user is writing class MyCustomComponent extends React.Component {
render() {
return (<a href={this.props.x}>Link</a>)
}
} then the fact that Custom components give developers great new ways to decompose an application into simpler part but the implementation hiding (which is otherwise a strength) make it harder to use code review and other techniques to avoid XSS. Would you rather I copy these responses there? @miesj, IIUC, interweave treats interpolated values and tags specified in JSX with the same level of trust. Is that right? The pre-interpolation hooks that worked for Polymer Resin treat the template as trusted, and are suspicious of interpolated values. |
To be clear, the conclusion from #3473 was that we implemented brand-checking for React elements so |
@gaearon Thanks for explaining. IIUC, that change prevented crafted JSON and objects that are mass-assigned from getting the same level of trust as the output of a JSX expression that produces a component. |
@mikesamuel Sorry, got a bit ahead of myself. You're right, as the markup would need to be a string, which is then safely parsed and filtered with Interweave, like so.
That being said, I could possibly bubble up the XSS filter functions for easy reuse. |
As an update, I floated reactjs/rfcs#55 (comment) but that is tabled. It sounds like React is interested in opt-in to XSS safety via integration with Trusted Types. |
You might interested in this warning that is being added for |
Do you want to request a feature or report a bug?
A bug, but a well known and worked-around one.
What is the current behavior?
produces a link that alerts.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:
The alert should not pop up.
A simple string that reaches an
href
attribute should not cause arbitrary code execution even with user interaction.What is the expected behavior?
A string that reaches a browser builtin like the
HTMLAElement.prototype.href
setter should not cause code execution.Discussion
Polymer Resin uses hooks in another webcomponents framework to intercept value before they reach browser builtins where they can be vetted. A similar approach could work for React.
It allows values to reach browser builtins when they are innocuous or have a runtime type that indicates that the author intentionally marked them as safe for that kind of browser builtin.
For example, an
instanceof SafeURL
would be allowed to reachHTMLAElement.prototype.href
as would any string that is a relative URL, or one with a whitelisted protocol in (http
,https
,mailto
,tel
) but notjavascript:...
.Many developers know that
<a href={...}>
is risky, but if the link is an implementation detail of a custom React element, then developers don't have the context to know which attributes they need to be careful with. They shouldn't have to either since it is an implementation detail.Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
I believe this is widespread across versions.
An earlier REPL I tried showed that it worked on version 16.2.0 from https://unpkg.com/react-dom/umd/react-dom.development.js but I don't know what version the jsfiddle above uses.
The text was updated successfully, but these errors were encountered: