Better Security for Cross-site Scripts

From RuntimeWiki

Revision as of 10:28, 10 July 2008 by Gerv (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

Contents

Title

Editing Better Security for Cross-site Scripts

Detailed write-up

Description

The “Same Origin Policy” is at the core of browser’s security model. Under the “Same Origin Policy”, a web resource can only interact with another web resource if and only if both resources are from the same origin.

However, there is a notable exception to this rule. The “Same Origin Policy” does not apply to scripts and thus enables something typically called “cross site scripting (XSS)”. With XSS, a web page from one origin can contain a script element from a different origin. More importantly, this “foreign script” element has full access to everything else on this web page. Namely, the cross-domain script runs with the same authority as scripts from the originating domain.

Why Is This Important?

The implication of Cross-site scripts (XSS) is that it can be intentionally or unintentionally exploited for security breaches. The followings are a few examples:

  • The cross-domain script can modify the DOM to display unintended information;
  • The cross-domain script can monitor user input and steal sensitive data such as credit card number;
  • The cross-domain script can steal cookies by sending all cookie issued by the originating server to some foreign server;
  • The cross-domain script can send background requests directly to the originating server to conduct ill-intended operations.

Reference 1 (http://en.wikipedia.org/wiki/Cross-site_scripting) has some detailed description of XSS and its problems.

At the core of XSS problem is the lack of any security “sandbox” for cross-domain scripts. Cross-domain scripting is powerful and enables a lot of services that web users enjoy (for example, GoogleMap widget), the lack of any security sandbox for cross-domain scripts makes any websites that use such technique highly vulnerable, resulting either intentionally malicious or accidental damages.

Technical discussion

A common vulnerability that allows malicious XSS attacks is when a server database simply echoes some user-generated content without appropriate escaping. For example, support a evil user is filling out comments on a form on a popular public site and enters "Space travel rules! <script type='text/javascript'>...grab cookies, send to evil site...<script>". Then, whenever other users cause his comments, the script logic executes within the domain of the public site, causing his cookies to be transmitted to the evil site. Note that "send to evil site" might be accomplished by requesting a JavaScript file, a CSS file, an image, or an IFRAME, and using URL parameters (i.e., the information after the "?") for transmitting the stolen information.

Another XSS attack vector leverages the innerHTML feature in browsers. If a public web site allows for HTML content to be uploaded, and that content were not filtered to remove <script> tags, that when the content is retrieved, any embedded content <script> tags would execute. (There are probably other attack vectors leveraging the javascript: protocol within a link).

In these cases, it looks to the browser as if the script logic came from the same site as the original web page. To eliminate these attacks, browsers need some sort of mechanisms to identify trusted script logic versus untrusted script logic, plus a way to have trusted script logic prevent untrusted script log from executing.

Possible Workarounds

  1. ADSafe (http://www.adsafe.org/): ADsafe defines a subset of JavaScript that is powerful enough to allow guest code to perform valuable interactions, while at the same time preventing malicious or accidental damage or intrusion;
  2. Caja (http://code.google.com/p/google-caja/): A source-to-source translator for securing Javascript-based web content; It "sanitizes" (transcodes and wraps) arbitrary JavaScript into safe JavaScript that cannot attack the rest of the content on the page. It achieves it magic via forbidden names, frozen objects, no shared global environment, internal names, no "this" stealing, and removing "with" and "eval" (although a safe "caja.eval" is available);
  3. Using “iframe” as a security sandbox: This approach has been proposed by various entities. OpenAjax Hub 1.1 also leverages this technique to solve mashup security issues;

Possible Solutions

List of trusted sites?

At the OpenAjax F2F on 2008-03-21, there was a proposal that we could address XSS by providing a list of trusted sites:

To which there was a response:

<slightlyoff> ... well, that doesn't entirely solve it
Adobe AIR approach

A recent release of Adobe AIR has features to prevent cross-site scripting vulnerabilities by disabling the ability to add new JavaScript logic to the application in selected scenarios. Some of this might be applicable to this requirement, but Adobe AIR is focused on desktop-installed applications more than web applications. (See [1])

<scriptkey>

Maybe this is a bad idea, but here goes nevertheless. How about if there is a new version of <meta> such as:

<meta scriptkey="<number>"/>

which provides a hidden key that only the originating web site could know (e.g., randomly generated with each session). The browser would parse/execute script logic that is included in the set of files that were listed before the load event is fired (the original application files therefore would have an implicit withscriptkey()), but for script logic that is parsed/loaded after the load event, then the browser will only execute JavaScript which supplies the given key. The web site's own dynamic SCRIPT tags would look like this:

<script type="text/javascript" scriptkey="<number>" src="..."/>

and dynamically added event attributes could be preceded with a special function call:

<img src="..." onclick="withscriptkey(<number>);..." />

with the requirement that browsers must hide the actual script key from all views of innerHTML and the DOM by showing zero instead of the actual number. This would make it so that JavaScript logic that is echoed from remote databases would not get executed, no matter if done via <script> tags, innerHTML, or javascript:.

This is just a brainstorm. There are probably lots of complexities with the above proposal and probably other superior approaches.

Something very similar has been proposed by Gervase Markham (http://www.gerv.net/security/script-keys/).

<module> tag and/or a revamped DOM and JavaScript

Doug Crockford has given keynotes lately where he calls for a more fundamental attack on security vulnerabilities, including major overhauls of how DOM and JavaScript work.

He has proposed the <module> tag (http://json.org/module.html) to associate a particular domain with a particular snippet of HTML and results in sandboxing that snippet from the rest of the document (i.e., DOM and JavaScript).

Doug has also proposed a safe subset of ECMAScript (someone, please insert a link).

Gears

Gears (http://gears.google.com) has cross-domain workers, which allow you to safely pass strings (but not execute JavaScript or expose cookies) between two sites that opt-in. Details here (http://code.google.com/support/bin/answer.py?answer=83193&topic=11692).

Mozilla's Site Security Policy

Mozilla is looking at four new HTTP headers to allow a web page to identify the whitelist of domains that are allowed to contribute JavaScript, whitelist of domains that are allowed to request a given resource, whitelist of domains that are allowed to be the target for cross-site requests, and the URI for where to POST whenever site security has prevented an operation.

Background material that request this feature

Discussion

In this section, the contributors should express their opinions about this feature request, such as providing particular technical analysis or describing in prose why this feature is important (or not). It is recommended that each contributor create his own level-3 sub-section (e.g., === Jon Ferraiolo Comments ===).

It is OK for others to insert comments within other people's sections, but as a courtesy please make sure that it is clear which part of the section is original and which section are annotative comments. For example, perhaps annotative comments would be colorized (e.g., enclosed by <span style="color:red">JON: Here is what I think about what you are saying.</span>).

Jon Ferraiolo comments

This is a complex issue, involving both browser complexities and security complexities. We want to make the Web more secure, but without breaking the existing Web, or making it a more secure web too complicated for mortals to use. The best exact solution probably will have to come from a comprehensive proposal from one of the browser vendors.

Kris Zyp's comments

These are extremely issues, however I don't think we have anything here that we should be recommending to browser vendors yet (except maybe the module tag). Caja and ADsafe are important, but they are still in development. Also, these tools can be used with existing technology (albeit there are some improvements to JavaScript that are being considered for ES3.1 and ES4 that will make it easier to use Caja). One of the most important browser technologies for making these technologies work is cross-site loading capabilites (XHR or XDomainRequest), so that scripts can be loaded and validated or translated prior to evaluation. Also, getters and setters (which is being added to ES3.1/ES4) are extremely important for creating reasonable DOM facades to provide to these untrusted scripts.

The module tag could be recommended for browsers, but the exact behavior of such a mechanism would be incredibly complicated as it has a very wide vector for attacks, I am not sure if Doug is even still pursuing this one.

Douglas Crockford comments

The good thing about the safe JavaScript subsets is that they do not require browser modifications. You can begin using them as soon as you develop enough nerve to trust them. Because none of the browser's vast array of vulnerabilities are repaired, there may still be risk. But the subsets will allow us to mashup now without being totally irresponsible.

There are changes that can be made to JavaScript that will make the safe subsets safer. ECMA TC39 is currently looking at this. This obviously does not help us in the short term. Ultimately, I believe that JavaScript and the DOM need to be replaced to correct the XSS problem.

Iframes are not currently a solution because of the top.location problem. If that could be corrected, then iframes with Cross Document Messaging could be used for safe mashups. This is something we should push on immediately.

Brad Neuberg comments

I'm not sure what the best technical mechanism is, but allowing for the following three use cases is important:

  • Embed a widget from a foreign domain that doesn't take any input data - we currently use JavaScript Includes for these. These can probably be safely sandboxed into an iframe of some kind. This is for widgets that just insert themselves and don't need selective access to the page or which don't need any programmatic input of data.
  • Embed a widget that needs parameters to run or needs to selectively get things from the page. The AdSense infrastructure would be an example of something like this. Its not just a JavaScript Include -- its a JavaScript include that is looking at some of the page's contents, plus the URL, to create ads that are aligned with the content being looked at.
  • Mash up multiple third-party web services from the client-side. Generally we've been returning JavaScript from these to get around the same-domain policy, but this exposes cookies and has XSS issues as well.

It seems like this proposal is related to having a better component or widget standard for the web as well. Caja is a good solution for sanitizing script as well and has come along nicely recently (disclosure: I work for Google, which has been developing Caja).

I don't really care what the exact technical solution is, though, as long as we get one that is good enough.

[Update] I'm confused -- does this proposal include better cross-domain mashups in general, or only isolating scripts from each other? If not, then we need a proposal for better cross-domain mashups that can be done securely, fast, and reliably.

Native JSON Parsing should be rolled into this, since native support for secure JSON parsing is instrumental to safer cross-site script security.

Nicole Tedesco's comments: implement a signed resource archiving solution

(From NicoleTedesco)  A generalized resource bundling solution (images, sound files, XML and even other HTML pages) with digital signatures can provide an additional option to control trusted access to cross-site features, while also minimizing HTTP connection and overall bandwidth consumption. For details, see my comments in the Ajax Toolkit Caching discussion.

Phase I Voting - Vote for Your Top 5 Features

NOTE: PHASE I VOTING IS NOW OPEN. (2008-04-01) We have now changed the voting procedure. Instead of putting votes on each separate wiki page, we are asking people to cast their Phase I Votes on the following wiki page:


Phase II Voting

More about this later.

Personal tools