views:

589

answers:

2

Does anyone know whether a DOM Node of type Text is guaranteed not be interpreted as HTML by the browser?

More details follow.

Background

I'm building a simple web comment system for a friend, and I've been thinking about XSS attacks. I don't think filtering or escaping HTML tags is a very elegant solution--it's too easy to come up with a convolution that will slip past the filter. The fundamental issue is that I want to guarantee that, for certain pieces of content (i.e. the content that random unauthenticated web users POST), the browser never tries to interpret or run the content.

A plain(text) start

The first thought that came to mind is just to use Content-Type: text/plain, but this has to apply to a whole page. You can put a plaintext IFRAME in the middle of a page, but it's ugly, and it creates focus problems if the user clicks into the frame.

innerText/textContent/JQuery

It turns out that there are some browser-specific (innerText in IE, textContent in FF, Safari, etc.) attributes that, when set, are required to create a single Text node.

JQuery tries to avoid the difference in browser-specific attributes, by implementing a single function text(val) that skips the browser-specific attributes and goes directly to document.createTextNode(text), which, as you can guess, creates a Text node.

W3 DOM Text Nodes

So I think this is close to what I want, it looks good--Text nodes can't have children, and it appears like they can't be interpreted as HTML. But I am not 100% sure from the official docs.

The part from textContent is particularly encouraging, because it says "on setting, no parsing is performed either, the input string is taken as pure textual content." But is this fundamental to all Text nodes, or only nodes on which you set textContent? This probably seems like a dumb quibble, but it might be important because IE doesn't support textContent (see above).

Back around to the initial question

Can anyone confirm/reject that this will work? That is, that a w3 DOM compliant browser will never interpret a Text node as HTML, no matter what the content? I'd be extremely grateful to have this tormenting little uncertainty resolved.

Thank you for your time!

+1  A: 

I don't think filtering or escaping HTML tags is a very elegant solution--it's too easy to come up with a convolution that will slip past the filter

That is absolutely untrue, filtering > to &gt; and < to &lt; will completely stop any HTML injection.

brian
I'm basing my paranoia on:http://stackoverflow.com/questions/53728/will-html-encoding-prevent-all-kinds-of-xss-attackshttp://blog.stackoverflow.com/2008/06/safe-html-and-xss/
elliot42
@surprise_ wrong. there are many other injection techniques, from encoding tricks, to attribute injection, JavaScript, CSS, etc
Zach
+2  A: 

Yes, this is confirmed, to the extent that for what ever browser it wasn't, that browser would have a serious defect. A text node that rendered anything but text would be a contradiction. By using document.createTextNode("some string"); and appending that node, the string is guaranteed to be rendered as text.

Zach