Log in

No account? Create an account
Previous Entry Share Next Entry
Javascript: how much of a threat is it currently, in practice?
Here's a bigger and more important question, that mindways just reminded me about in a comment. I'm looking for opinions: should Querki permit Javascript on pages?

The thing is, *preventing* Javascript has all sorts of costs. Not only does it mean that I can't let people put arbitrary HTML into pages, it means they can't use arbitrary CSS either. (There are more ways to get Javascript into a page than you may realize -- stripping it out reliably is *very* hard.) For Joe-in-the-street end user that doesn't matter, but for the folks with a little technical skill, trying to build cool and pretty shareable Apps, it's a very serious limitation.

So the question is, in the modern environment, with modern browsers, how *dangerous* is Javascript? I'm already planning that every Space will have its own subdomain, which I believe makes most easy XSS attacks fail. (Since browsers have gotten pretty strict about crossing domain lines.) It *does* mean that Apps will be able to load arbitrary Scripts, which means that they can build fairly arbitrary mash-ups, but that's potentially very powerful and not too terribly different from your average website. (I love the potential for mash-ups -- it means that users can, eg, build Apps that embed Google Maps without waiting for me to build that into the heart of the system.)

So I'm looking for opinions here -- some of you have done more security-wonkery than I, and I'm curious what your take is...

  • 1
One thing to keep in mind that came up with user-created sites at MIT: if your website is at foo.querki.com, and mine is at bar.querki.com, by default I can set a querki.com cookie that browsers will send all query.whatever websites. This can let me impersonate a cookie that foo.querki.com expect to only have been set by code running at foo.querki.com. (See http://publicsuffix.org/ and http://en.wikipedia.org/wiki/HTTP_cookie#Supercookie.)

Hmm; interesting. I'm not sure how much that worries me, but it's certainly a non-zero concern. How did MIT handle it?

Some people were trying to get mit.edu on the Public Suffix list I linked to (there are already some private domains there), but I don't think that ever actually happened. One way people handle it in real life is to make sure that your cookies aren't forgeable by, e.g., signing them, but obviously that's not something you can enforce if people can write arbitrary javascript.

Also, on a non-security tangent, allowing Javascript or other nontrivial HTML also makes it impossible to guarantee any sort of pretty PDF/ebook/email/RSS conversion. And people are going to C&P things they don't understand and then not understand why their pretty scrollbars broke some other feature. But, as an advanced user, I'd want to be able to specify spiffy Javascript things and provide some sort of fallback if I expected to be using multiple formats, so it's a thorny issue.

Just so. I'm seriously thinking about dsrtao's suggestion below, of allowing it only if you push the Big Red "I am intentionally using Javascript" button for your Space -- that may be a pragmatic compromise.

I guess one way to do it would be to isolate Javascript into explicit widgets or something, so you could have explicit fallback for non-Javascript-supporting formats and wouldn't be able to use it without some understanding that you were doing something weird. But dunno.

Systems like LiveJournal have gone so far as to develop their own theme scripting setup separate from the big systems in part because of problems like this.

It essentially means that in the default model for security for webapps, the cookies for the main site can be stolen by anyone who has access to write Javascript in any page in any subdomain, which usually means (in my experience, at least?) that the attacker could then act as any user they could get to hit the page.

I'm sure there are ways to cope with this that aren't immediately apparent to me -- obviously, tying cookies to IPs would be one approach that might help, but then you break logins from different locations without more work, etc. (LiveJournal does this by a more complex login system, where when you want to login, you're redirected through the main site, which then redirects you back to the subdomain with a subdomain specific cookie... or something like that. The details are fuzzy :))

I think user security when content creators are allowed to write Javascript is a difficult, if not impossible, process. (Though I think you've come to largely the same conclusion anyway.)

I'm sure there are ways to cope with this that aren't immediately apparent to me

Actually, the easiest apparent way would be that the main site and the user pages are different domains -- have "querki.net" for the main login and "querki-apps.net" for the individual Spaces.

But the point's well-taken. I think I'll start with a conservative stance, and then see about broadening gradually as we understand the requirements better...

I run with javascript disabled via noscript, and only grudgingly allow scripts selectively when I have to. No love.

The BEAST exploit demo code is pure javascript, by way of example of what can go wrong.

Note that the risk of exploit is to your visitors, not to your server. You can't control your users configuration and lack of security, but people who keep a tight configuration would like to be able to use your site without being forced to step back their security posture.

If you are going to use it, and require the client to accept it for the site to function, be stringent with controls to protect the client. Use output encoding in addition to input validation, set all the available security bits on your cookies, check the OWASP page on XSS prevention.

Note that the risk of exploit is to your visitors, not to your server. You can't control your users configuration and lack of security, but people who keep a tight configuration would like to be able to use your site without being forced to step back their security posture.

This is a good reminder that Querki *itself* shouldn't be unnecessarily dependent on Javascript (an interesting point for me to consider itself), but that's not really the question. This is all about whether to allow Apps built *in* Querki to contain Javascript. I'm entirely sanguine if such Apps break when the user has noscript turned on -- that's their own choice.

What I'm trying to assess here is realistically, what is the danger to my end users? What is the current level of threat from Javascript? Are there ways in which a Querki-based App is riskier than one built on Joe Random Webserver? Etc -- this is all assessment of risk to my users, and trying to balance that against the potential value of allowing App developers access to all the usual HTML/CSS capabilities. kihou's point above about cookies is precisely the sort of thing I *am* especially worried about, and need to chew on.

(I'm not worried about risk to the site itself. On *that* side, it's mainly about paying attention to SQL injection, and making sure that my server-side programming language is sufficiently robust -- making sure there are no easy ways to DoS the site with infinite loops, and things like that.)

I, likewise, disable Javascript by default. I have no particular desire to be executing arbitrary third party code.

The risk is huge, and current web technology doesn't allow for a secure way to sign the code or otherwise ensure its safety.

While disabling all Javascript would be hard, I'd start with readily achievable filtering. Yes, there are lots of ways to insert javascript into a webpage, but start with the low hanging fruit.

I dunno -- half-implemented security is sometimes worse than no security at all, since it can lull folks into complacency...

It's a big hairy deal.

You can reduce the unintentional risks by adding a checkbox to the submission for any edit that could contain JavaScript:

[ ] This change includes JavaScript, please allow it.

and filtering it out otherwise.

That can help with people accidentally adding things that they don't understand. It doesn't help with people intentionally adding things beyond their ken, nor blackhats.

Most people do not want arbitrary HTML. Beginners want a point-and-click markup with all the obvious options available, and intermediate folk usually prefer MarkDown or a similar interpolation layer.

| Column1 | Column 2 | Column3 |
| data | data | data |

is both as complex and as effective as most people need.

Hmm. Interesting middle ground -- allowing Spaces to have Javascript, with a bit of "caveat emptor" for the App, but making a *reasonable* effort to filter otherwise. I suppose that might reduce the temptation for sleazeballs to try secretly injecting Javascript where it's not welcome.

Mind, my concern mainly that:

and filtering it out otherwise.

is downright hard to do properly. It's easy to strip out *obvious* Javascript, but there have been many exploits that demonstrate ways around those. Heck, I've done it myself occasionally, doing proof-of-concept experiments that major sites (which ostensibly didn't permit Javascript) could have it injected if I was clever enough.

Still, this is a very intriguing suggestion. Among other things, it would allow us to show a clear "Requires Javascript" flag on Apps, which I think many of my friends would appreciate when deciding whether to try an App or not. Couple it with a clear statement that attempts to circumvent this *will* get you permanently booted, and an involved community keeping an eye on things, and it might be good enough in practice. Thanks!

Most people do not want arbitrary HTML. Beginners want a point-and-click markup with all the obvious options available, and intermediate folk usually prefer MarkDown or a similar interpolation layer.

Oh, sure, and that's the 95% case. (Indeed, exactly the 95% case -- I'm currently looking at the JVM-based Markdown-flavored engines, to decide which one I'm going to use as my starting point.)

But even the Markdown site itself is very explicit that it doesn't do everything, and that you *should* fall back to HTML when you need edge-case power. Indeed, vanilla Markdown doesn't have have the Tables you illustrate, as I understand it -- that's a common extension.

I'd like to permit that for App developers. Only a few percent of my audience will care, but that's exactly the group who are going to be developing some of the most interesting Apps.

And really, this is even more about CSS than HTML. I'd like to allow Spaces and Apps to be able to specify real CSS (or maybe LESS), without having to write yet another damned templating engine. But CSS can contain Javascript, so it has all the same potential issues as HTML...

intermediate folk usually prefer MarkDown or a similar interpolation layer [to HTML].

Really? When I started running a wiki, I had to gently remind a number of users that the markup language was generally easier for everyone to read when looking at the source. Not programmers, either.

(Admittedly, the plural of "anecdote" is not "data".)

I suspect it depends a lot on your user base. For many of my early-adopter close friends, I agree that they might pull out HTML simply out of habit.

But I suspect that most of my target audience will prefer Markdown. Hell, *I* prefer Markdown -- for most purposes, it's much faster to type and less persnickety. (One reason I chose Markdown is that it is the closest syntax to what I type anyway...)

(Deleted comment)
Yeah, my assumption is that 80-95% of my users will prefer a WYSIWYG editor -- that should be the default by sometime middle of next year. Markdown will be mainly for power users, and HTML will, at best, be for power users dealing with edge cases...

Ah - this was about 5-6 years ago. And indeed - at the time I installed the wiki, there was minimal WYSIWYG editing (there was a plugin, but it was very flakey and very slow); the modern version has a much better one.

As a user of a querki app, I may choose to trust the developer, but not necessarily all the other users.

You want your developers to be able to send javascript to the client, but users of the app should not be able to store and reflect javascript to other users. A datastore system that enforced output encoding would help -- the application itself can generate and emit script, but the database and any tainted storage should not be allowed to.

You are still subject to violations of the DOM model whereby scripts from other sites can steal session or other sensitive data from the client, such as described above.

Hmm. That's a reasonable and interesting point. I hadn't even been thinking about Javascript in the *data*, but you're absolutely correct that that's a danger -- indeed, probably a much more significant danger.

Thanks: I agree that output encoding is essential, so I should put that on my to-do list...

Another vector is system error messages reflecting user input - ie "I'm sorry I couldn't find the file: *data stealing javascript here*" which could be caused by me getting clickjacked from another window or frame.

If I'm running with script disabled I'm safe, but if I've enabled it to access your site, my session cookie or other data is now gone.

Supporting mashups mean sites in querki will be framed in other sites, wich means they are subject to clickjacking.

Well, I think you've made a compelling argument that Querki *itself* should not require Javascript, and I've noted that as such. As a security-conscious user, I should be able to use Querki with noscript turned on. (That'll occasionally drive me a little crazy as a developer, but it's a good idea on several fronts.)

Supporting mashups mean sites in querki will be framed in other sites, wich means they are subject to clickjacking.

Strike that, reverse it -- I'm talking about the ability to frame other sites inside Querki. Embedding a map is pretty much the canonical example.

But the clickjacking point is a good one regardless: I should think about having some framekiller bits in there, entirely separate from the Javascript-in-page question.

Overall, this conversation is leading towards a model where things are HTML-stripped by default, with exceptions possible but very limited...

  • 1