Never untaint

For the last few weeks, Aaron and I have been worrying about the state of XSS security. As we have said before, input sanitization is not enough, you need something like SafeERB for all external data.

But after looking at XSS Shield, and thinking a bit more, I have concerns about SafeERB's approach to safety. Here's the problem:

  • External data is marked as tainted. Great care should be taken in using tainted data in any potentially executable context.
  • SafeERB sanitizes strings against XSS, and then untaints the strings so that you know they are safe in an HTML context.

Notice the subtle asymmetry. External data is dangerous in any executable context. SafeERB untaints data after making it safe for only one specific context--HTML. What if your freshly untainted string contains SQL? Shell script code? Or some DSL you never heard of?

You could argue that the data is being marked untainted in the view layer of an HTML MVC framework, so we don't have to worry about non-HTML dangers. I don't buy this at all. How can you be sure that none of your Rails code will ever be repurposed in another context? Sounds like a recipe for legacy to me.

XSS Shield takes a more cautious approach. Instead of calling untaint, XSS shield uses Ruby's open classes to define new methods such as mark_as_xss_protected. So you can leave a string tainted, but mark it as XSS safe.

Let me be clear: SafeERB is way better than doing nothing. But I am moving toward the conclusion that you should never untaint data. What do you think?

Get In Touch