7

This is kind of a bar-bet question. An acquaintance of mine has made the claim that, given an arbitrary glob of HTML, it can be completely prevented from executing JavaScript if, before slapping it into a webpage, you replace all instances of < with &lt; -- and make no other changes.

I am not convinced my acquaintance is correct, but I can't think of a counterexample either. Can anyone prove or disprove?

Clarification: Assume that the escaping happens server-side, and the glob is inserted as the contents of a normal element, e.g.

<p>{{ GLOB GOES HERE }}</p>

Also, assume a client that implements the HTML5 parser algorithm, correctly; we're not worried about bugs, legacy parsers, or scenarios that apply only in XML or SGML.

Further clarification: The OWASP rules are deliberately conservative. Because this is a bar bet, we want a pedantic answer, not a conservative answer.

7

Inside the element, the parsing mode is in data state. The only special characters that can escape data state are < and & (http://www.w3.org/TR/html5/syntax.html#tokenization sec.8.2.4.1).

If you replace all instances of < with &lt; then you only need worry about &.

In HTML4 and XML, you would need to consider which entity references are available for replacement, and whether any of them could be used to inject a script or other attack vector. This could be a problem, for example, if the markup refers to an external DTD and the attacker can redirect a network download of the external DTD to one of their own choosing. This is one reason that many XML and HTML parsers do not go to the network to resolve system identifiers.

However, HTML5 only permits & to be used for character entities, none of which can be used to escape data mode.

Hence, in the absence of bugs in the parser and in the markup, your acquaintance is correct.

  • This is the pedantic, standard-citing answer I was looking for. Thank you. – zwol Nov 30 '14 at 16:22
5

It depends on where within the HTML document the data is printed as there are different contexts within different rules. Replacing a literal < by &lt; is only viable when < is a special character, which would change the current parsing state.

There is a quick overview of prevention rules in OWASP’s XSS (Cross Site Scripting) Prevention Cheat Sheet, which should give you a hint of what you should be aware of.

4

Depends on a lot of factors.

If the malicious input (all user's input is malicious by default) is echoed just to your HTML body and your server sends the headers "Content-Type: text/html; charset=utf-8" and "X-Content-Type-Options: nosniff", the answer is yes, this method is secure enough.

When I say HTML body, I am supposing you are echoing the input to <html><body>INPUT_HERE</body></html>.

If you just echo the input to a blank page, without a few bytes before the input, Rosetta Flash attack can be used.

3

This is very bad practice. You are keeping a blacklist. But recommended way is keeping a whitelist which give only allowed chars after a filter.

Answer to your question is, < can be hex encoded and write in other encoded schemes. So Simply replacing < with &lt; would not be adequate.

  • 1
    Since the set of characters is finite, allowing only whitelisted characters is equivalent to removing any blacklisted characters. – Gumbo Nov 26 '14 at 7:40
  • @Gumbo It is not easy. In Unicode there are many chars. So blacklist will be huge specially with encoded chars. – Kasun Nov 26 '14 at 7:47
  • I’d rather say a whitelist would be huge (i. e., UCS \ {<}) in opposite to a blacklist (i. e., just {<}). – Gumbo Nov 26 '14 at 7:50
1

Where are you parsing out the <? If it is on the client, then you have have only maybe stopped a ten year old hacker (but not this ten year old hacker).

However, if you are parsing out the executable code server-side, then yes, you've effectively stopped this particular form of injection -although there are more complete and secure ways of doing this.


Perhaps I am missing the gist of your question so if you are simply asking if you can replace all instances of < with (anything else), then the answer is yes. Yes, by default, this will prevent all javascript tags from being parsed and ran because the character entity &lt; is not processed when the DOM loads.

Here is a reference to accomplish what you may be asking. I left my first bit up because it is still important.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.