Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

We have a simple Blog system that allows users to input html and JavaScript to build a blog page. I'm aware that allowing javascript open up the door to xss attacks. We do however need to allow users to insert javascript, as an exmple would be allowing the user to insert a google ads code which contains JavaScript. The question is how go about allowing JavaScript while preventing xss. I was assuming https would secure cookies and prevent cookie stealing, but users on stackoverflow said otherwise.

share|improve this question
    
Does the JavaScript input need to be available right away? This may be to burdensome, but what about reviewing and aproving user submitted JavaScript? –  this.josh Jun 30 '11 at 23:17
    
"as an example would be allowing the user to insert a google ads code" <- isn't this the definition of cross site scripting? You just want to prevent cross site scripting vulnerabilities? –  jrwren Jul 7 '11 at 12:15

5 Answers 5

up vote 10 down vote accepted

https is all about encryption and ensuring server identity to prevent other people from listening to the traffic. So it does not help at all against malicious JavaScript code within the bounds of the same origin policy.

There is a flag on cookies called httpOnly which prevents simple JavaScript code on modern browser to access the cookie. But this does not fix the issue, it just makes exploits a bit less simple: The JavaScript code can directly trigger form submissions with the permissions of the current user. Since the JavaScript is on the same domain, it has access to CSRF tokens. The browser will include the cookie on the form submission without the JavaScript code needing to access it. (And there is a number of bugs around HttpOnly, for example some browser allow to read the cookie from an XMLHttpRequest object.)

Furthermore the JavaScript author may replace the current page content with "Your session has timed out, please login again" and its own login form. But the form he adds does not point to the login URL of your server but to a server he controls. Or even more subtle, there may be a cross-domain Ajax call in the event handler of the submit-button.

There is a rather simple solution in two steps:

  1. Filter all non trusted markup, including all JavaScript. If you are using PHP, you can use HTML-Purifier. There are similar libraries for all common languages.
  2. Provide harmless placeholders ("widgets"). So instead of letting your users embed JavaScript code directly, they must write something like <div id="googleadd">identifier</div>. A piece of trusted global JavaScript code can replace those code fragments with the real add code. Make sure to properly escape input parameters. This will limit your users a little in what they can do, but it is pretty easy to cover all common use cases.

It does make sense to google a bit as there are already a number of Widget libraries out there; although most of them still require JavaScript calls.

share|improve this answer
    
Good explanation of what https does, and cockie access. –  this.josh Jun 30 '11 at 23:15
    
@Hendrik, this does not answer the question -- you must have missed @Hussein's statement that users must be allowed to include Javascript. If you filter all markup (e.g., with HTML Purifier), that will strip all Javascript -- but the original question-asker said Javascript must be allowed. Putting the Javascript in a div does nothing for security; the untrusted Javascript can still do everything, regardless of where on teh page it is placed. –  D.W. Jul 2 '11 at 7:18
1  
@D.W., no, I have not missed that part of the question. But I looked at the reasoning he gave for that statement and provided an answer for that instead. The idea is NOT to put the JavaScript into an div. The div only contains information that is interpreted by trusted JavaScript provided by the site owner. As I said, this does not give authors the full power of JavaScript, but it can be used for all common use cases, such as embedding known addvertisment systems. –  Hendrik Brummermann Jul 2 '11 at 8:03

HTTPS doesn't prevent stealing cookies, HTTPOnly flag does. I would recommend (if it's possible) to have a library of "widgets" users can include in the page and configure. Then you can just insert the JavaScript code with configured parameters without allowing user to write JavaScript code.

If you enable your users to insert their own JavaScript code, they can do things like updating the login form of your blog system to send credentials to another server, so that if some user visits the malicious blog page and decides to log in to your system on that page, his credentials could be compromised.

share|improve this answer
    
"HTTPOnly flag does [prevent stealing cookies]" but it doesn't prevent sending them to the original website, and reading resources obtained by sending them to the original site, so HTTPOnly adds very little security (if it adds any security at all). Note that in most cases the security sensitive cookies are opaque values (like a session ID), so that the only possible use of them by an attacker is to send them back to the the original website anyway. –  curiousguy Jun 20 '12 at 2:50
    
(...) And some websites only allow interaction from the original IP address (a terrible idea IMO). IOW, HTTPOnly prevents attacker from doing something he wouldn't do anyway. So if someone thinks HTTPOnly is the solution to a security problem (any security problem really), the odds that he is wrong is 99:1. –  curiousguy Jun 20 '12 at 2:52

No, HTTPS doesn't stop this threat.

If your users must be allowed to include Javascript they have written into the page, this is a very challenging problem. What you want is some kind of Javascript sandbox. @Mike Samuel's recommendation of Caja is a good choice of Javascript sandboxing technology. Other possibilities in this space include Microsoft's Web Sandbox, Yahoo's AdSafe, Facebook's FBJS, and probably others I have missed.

Please understand that while solutions do exist, they won't be entirely trivial to deploy. You've stumbled upon a hard problem in web security; the web just wasn't designed to support this kind of thing, and as a result, the solutions necessarily end up being a pretty complex piece of technology. So you will probably need support from a capable developer to deploy and integrate one of these solutions into your web site.

share|improve this answer
    
As D.W. said this gets really complex and wildcard certificates, that are required to isolate one untrusted JavaScript code from another untrusted JavaScript code, are quite expensive. On a small site it is unlikely that you will make enough money with advertisement to recover those costs. So you should think in detail about whether arbitrary JavaScript code is really, really needed. –  Hendrik Brummermann Jul 2 '11 at 8:13
    
@Hendrik, what did you meant about "wildcard certificates that are required to isolate one untrusted JavaScript code from another untrusted JavaScript code"? Usually, the biggest drawback of wildcard certs (besides the price), is lack of isolation. I think I didnt understand what you mean... –  AviD Jul 5 '11 at 0:21
1  
@AviD, You are right that a compromise of one server, which exposes the private, key affects all other server using the same key. In this case, however, there is only one server: The isolation is enforced by the java script engine in the client according to the same origin policy. Using individual certificates is not an option unless the userbaes is extremely small because it requires one IP address for every certificate to be compatible with common browsers. –  Hendrik Brummermann Jul 5 '11 at 5:51
    
@Hendrik ah, I think I understand now what you mean. Not that the wildcard enforces the isolation, but that in certain scenarios it is necessary, to be able to implement in the way you describe. –  AviD Jul 5 '11 at 7:12

Shameless, but relevant plug:

From code.google.com/p/google-caja/

Caja allows websites to safely embed DHTML web applications from third parties, and enables rich interaction between the embedding page and the embedded applications. It uses an object-capability security model to allow for a wide range of flexible security policies, so that the containing page can effectively control the embedded applications' use of user data and to allow gadgets to prevent interference between gadgets' UI elements.

share|improve this answer

If you allow google tracking, you already allow XSS, because google-analitics is by definition an XSS.

You could set up a template where the user would only paste his ID that you could sanitize properly.

You can never allow javascript input and be safe. Try working with the below code. Do you think it's safe? Does it have any of the keywords that suggest danger? :)

$=''|'',_=$+!"",__=_+_,___=__+_,($)[_$=($$=(_$=""+{})[__+__+_])+_$[_]+(""+_$[-__])[_]+(""+!_)[___]+($_=(_$=""+!$)[$])+_$[_]+_$[__]+$$+$_+(""+{})[_]+_$[_]][_$]((_$=""+!_)[_]+_$[__]+_$[__+__]+(_$=""+!$)[_]+_$[$]+"("+_+")")();

Spoiler: it's alert(1)

share|improve this answer
    
In the days of jQuery, $ suggest danger. :-) –  Hendrik Brummermann Apr 6 '12 at 22:09
    
It can be anything, You could replace $ in above code with anything including any of these: øµª and it will do the same. It's just a character. –  naugtur Apr 11 '12 at 16:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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