News for hackers. Stuff that matters.
Re:Break Google by pavpanchekha on Thursday September 15, 2011 @09:22PM (#3002769)
Oh, cute. Yet another injection flaw in Google.

Guys, (and I don't mean Google, I mean all of us), don't fix injection by plugging injection bugs; put together some framework that actually avoids all of these problems (or at least doesn't let you add bugs).

Re:Break Google by nokcha on Thursday September 15, 2011 @10:57PM (#3003012)
This is actually a hard problem in the general case, and it is an active area of research. One promising approach is static taint analysis, wherein the source code of a web app is analyzed to detect whether "tainted" output is given to a sensitive "sink" without being properly sanitized. See, e.g., Omer Tripp et al., "TAJ: Effective Taint Analysis of Web Applications" (PLDI 2009) (http://www.cs.tau.ac.il/~omertrip/pldi09/paper.pdf).

As an example of a difficult case, consider the following pseudocode snippet:

  ...
  if request['raw']:
      print("Content-Type:text/plain; charset=utf-8\r\n\r\n")
      print(doc)
  else:
      print("Content-Type:text/html; charset=utf-8\r\n\r\n")
      print(html_sanitize(doc))
  ...
In one branch, doc must be HTML-sanitized; in the other branch, it must not.
Re:Break Google by colanderman on Thursday September 15, 2011 @11:08PM (#3003040)
That's a poor example. I would never send a document as HTML without tags. html_sanitize() should really be generate_html(), which adds structure to the document.

What the GP is saying (and I agree with) is that generate_html() should use a library which understands HTML structure and only allows content to be generated using a strict API (no doc+="<foo>bar</foo>" garbage).

Such a discipline greatly reduces the chance of injections, to the point where you have to actively write code to create injection points. And it's simple to follow: any time you write HTML, use the library.

Taint analysis sounds nice in theory, but you can get the same effect by writing code modularly (i.e. only one small module can actually access the raw output stream) and using libraries to create structured data.

Re:Break Google by jerf on Thursday September 15, 2011 @11:30PM (#3003085)
You don't know where "doc" is coming from from a snippet like that. I use logic moderately similar to that for my blog software. If I'm writing the blog post, pretty much pass through what I wrote. If it's a comment (back when I had them), process the heck out of it. The blog post itself is a blob of HTML, basically.

I do not currently write my blog posts in a templating language (any more than anyone else does), though Hamlet [1] has me sort of tempted as it is so close to what I write anyhow.

[1]: http://www.yesodweb.com/book/templates

Re:Break Google by defen on Friday September 16, 2011 @04:18PM (#3006142)
It's not a poor example, and it's not about sending the document without tags. It's about whether special characters should be escaped, and the answer depends on the Content-Type that the client requested.
Re:Break Google by Peaker on Friday September 16, 2011 @09:59PM (#3007002)
A framework could use static types to tag whether it is escaped or not.

Then, the framework could map different kinds of requests (e.g: raw content vs. html content) to different types.

Then, the only way to convert between the types are functions that do proper escaping.

Re:Break Google by MostAwesomeDude on Friday September 16, 2011 @08:01PM (#3006782)
Re:Break Google by pavpanchekha on Thursday September 15, 2011 @11:49PM (#3003130)
You're making the same mistake made by people who mistake good static type systems and type inference. Yes, it would be nice to infer the correct escaping function; but forcing people to escape somehow would be sufficient.
Re:Break Google by AndyKelley on Thursday September 15, 2011 @11:19PM (#3003059)
Django does this.
Re:Break Google by pavpanchekha on Thursday September 15, 2011 @11:45PM (#3003117)
No. Django solves the 90% problem, which is usually a fine approach but will llikely lead to security vulnerabilities down the line.

I'll refer to something I wrote last time I had this argument: http://pavpanchekha.com/programming/injection.html.

Re:Break Google by orclev on Friday September 16, 2011 @11:59AM (#3004968)
Nice article. In response to the last part I can think of a way to achieve the sort of smart escaping via template you talk about using Haskell and Hamlet (among other templating systems used by yesod). I believe, although I can't absolutely confirm that Hamlet already performs context appropriate escaping, based mostly on the type signatures and the names of a few of the functions.
Re:Break Google by gregwebs on Friday September 16, 2011 @05:05PM (#3006309)
Yes, Hamlet does context specific escaping. It will handle all the examples given, except you can't mix your javascript in with your html (which is generally good advice anyways).

I disagree with the articles premise that injection is always a display issue. In the [Yesod web framework](http://www.yesodweb.com) which uses Hamlet, we sanitize, not strip html by default before it is ever put in the database. The more you can make injection not a display issue, the better- you just have to know your options.

Re:Break Google by dmm on Friday September 16, 2011 @10:35AM (#3004567)
You should replace your '<' with '&lt' if you're going to claim your page is xhtml.
Re:Break Google by pavpanchekha on Friday September 16, 2011 @04:44PM (#3006231)
Thanks. Pages are compiled with org-mode, I'll report a bug.
Re:Break Google by dmm on Saturday September 17, 2011 @10:24AM (#3008074)
I love org-mode.
Re:Break Google by AndyKelley on Sunday September 18, 2011 @05:59PM (#3011388)
I don't know what you mean by "90% problem", but unlike what your blog article suggests, Django's template engine escapes everything by default. You have to explicitly pass content through a filter to request that it not be escaped.

Based on the fact that the suggestions in your blog article could easily support someone forgetting the "|escape" on a variable, I would accuse your methodology of only solving the "90% problem".

Re:Break Google by abeld on Thursday September 15, 2011 @11:44PM (#3003116)
How exactly?

Due to django's "we want the templating system be general, to be usable for stuff other than html", it can't provide support for such 'guarantee that the output is well formed / valid / has no injection attack entry points' features.

Re:Break Google by AndyKelley on Friday September 16, 2011 @01:06AM (#3003270)
> How exactly?

Everything is escaped by default, and you have to explicitly request for your content to be unescaped.

Re:Break Google by wisty on Friday September 16, 2011 @07:23AM (#3004012)
OK, you escape stuff. Great.

How do you handle user-submitted image tags? Do you allow rich formatting, and if so, how do you sanitize it? (see http://www.codinghorror.com/blog/2008/08/protecting-your-coo...)

I think that Django uses sha for password hashes. They should use bcrypt, right? Did you turn on XSRF protection (which I think is off by default)? Are cookies secure?

Web security is not as simple as 's.replace("<","&lt;")' (escaping by default).

How do you generate slugs? Could someone put something nasty in a pathname or URL?

Django is not secure. You can secure it, with minimal effort, if you keep things radically simple. But you do need to know what can go wrong, so you don't introduce any "features" that are actually "gaping security holes".

Even if you do everything right, it doesn't mean that Django is magically secure no matter what people use if for (obvious, yes, but this is HN and sometimes failing to point out the obvious can get you downvoted). That's why people are objecting.

Re:Break Google by Pewpewarrows on Friday September 16, 2011 @09:21AM (#3004311)
Handling user-submitted image tags is (in my opinion) way outside the scope of the framework. Which tags and attributes to whitelist, or whether to use html markup at all compared to a different language like markdown, is very project dependent. If you have to, just install BeautifulSoup or any of the other great libraries that have cropped up in the last year or so to handle the sanitizing.

Django uses sha for password hashes because until recently there hasn't been a better library to ship with natively across all the platforms that Django supports. If you know you'll only be working on *nix, django-bcrypt can enhance the default password hashing behavior. As other commenters have noted, they're moving to PBKDF2 in the near future as a better included hashing library.

CSRF is on by default. If you need secure cookies and HSTS headers, there's a package that provides them called django-secure, which last I heard is being rolled into Django proper in the near future.

Django prevents path traversal and anything else you can imagine that might be nasty in a URL. The auto slug generation included.

So how exactly is Django not scure again? Where are the "gaping security holes"? Or do you have no idea what you're talking about.

Re:Break Google by jwpeddle on Friday September 16, 2011 @08:06AM (#3004105)
CSRF in on by default. Cookies could be more secure, and it's being worked on. Django is moving to PBKDF2 (there's no pure python bcrypt lib). There's not really opportunity to do anything interesting with slugs.

Like any framework, there will always be room to improve security, but it does do very well out of the box. At least it makes you work to expose anything obvious.