2

User generated links in an href tag can look like:

javascript:(() => {alert('MALICIOUS CODE running on your browser')})();

which i just injected using an input field on a page that does not check on the server, that URLs start with http / https. On the react-rendered page i could later click on the link, and voila my code is running.

Why does that work, when it is often stated:

react automatically escapes everything for you. (What does it mean when they say React is XSS protected?)

headphones
  • 81
  • 1
  • 8
  • _"on a page that does not check on the server"_ - there's your problem. – Joseph Oct 20 '17 at 12:33
  • So what does this then actually mean at all: "React is XSS protected?"... Isn't XSS usually handled during **output** aka rendering. – headphones Oct 20 '17 at 12:34
  • The thing is, the only source that was taking about this was this blog: https://medium.com/dailyjs/exploiting-script-injection-flaws-in-reactjs-883fb1fe36c1. I'm sorry if my question appears to be a bit rude, but i'm quite shocked currently that nobody else pointed to that. Most resources are blantly stating: It escapes XSS, which is, especially for the beginner or non-security-expert, a bit vague. Also why isn't this a question for SO? – headphones Oct 20 '17 at 12:43
  • 3
    How do you draw the line between XSS and legitimate use case though? You've accepted that as valid input from the user and told React to put it into the `href` attribute, it's valid and doesn't change the structure of the document itself - so why should React stop it? If you try to set something and break out of the `href` like `"/>` it will escape that for you. This PR has some discussion on this: https://github.com/facebook/react/pull/1461 – Tom Davies Oct 20 '17 at 12:59
  • Yes, this is also discussed here. https://github.com/facebook/react/issues/3473. I just hoped to find it in a more prominent place like the docs. – headphones Oct 20 '17 at 13:12

1 Answers1

0

When react documentation points that "Everything" is escaped it just means that if you add some children to a JSX element, "Everything" in that children will be escaped.

For example in:

const element = (
  <h1>
    Random text
  </h1>
);

Everything inside the h1 will be escaped, so if instead of "Random text" you want to display some user text coming from an input field, you are safe, any malicious script will be escaped.

WARNING: This does not mean you do not have to worry about XSS at all if you are using React.

You can still get an unsafe string from that input field (or an external source, as an API, converting a JSON object, etc) and place it on element props, or using dangerouslySetInnerHTML, or directly on html attributes as href, style.. etc where that malicious code will run.

So if you really need to place text on those props is your responsibility to sanitize the data before using it. Same as usually is done in the servers when saving data entered by a user, this data has to be sanitized so that code is not saved in the DB.

Carlos Ruana
  • 2,138
  • 1
  • 15
  • 14