Securing Untrusted Scripts Behind Firewalls

# Securing Resources from Untrusted Scripts Behind Firewalls

# by

# Ray Whitmer and Harish Dhurvasula

## Introduction

This page describes an alternative mechanism which can be used to protect all internal resources against requests from sandboxed scripts. This should especially be implemented for SOAP calls by untrusted scripts. When an attempt is made to access a resource at a previously-unknown URI, the sandbox reads a file at that domain with declarations to determine whether access is permitted to the script. If the file is not there, access is denied.

## The Problem

External untrusted scripts loaded behind a firewall are executed in a sandbox. These scripts may legitimately require access to external resources, but permitting them to access internal resources permits the compromise of these resources that would normally not be available to applications outside of the firewall. The sandbox must distinguish and protect internal resources.

## Client-controlled Solutions

Several client-controlled solutions have been designed to prevent sandboxed applications loaded behind a firewall from compromising other resources protected behind the firewall.

### Same Source Restriction.

By restricting sandboxed scripts to access only resources in the domain from which they were loaded, any script loaded from one domain into another is prevented from accessing resources in the domain into which it has been loaded. This policy has generally been successful in sandboxing Javascript and Java applets across the web.
If the sandbox is unable to distinguish the common URI substring of the domain to be trusted from similar URIs of untrusted domains, then it could allow a script loaded from an indistinguishable domain to exploit firewall-protected resources.
Also, this technique prevents the script from accessing many legitimate external resources not provided in the same domain as the script. This prevents a script from accessing web services and data published from any domain besides its own.

### White-listing

By creating a white list of trusted URIs from which scripts are trusted to not compromise internal resources, it is possible to release domains from the stricter same-source sandbox. A white list is a good tool for including always-trusted domains, but on the web, it is often a script from a relatively-untrusted domain that must be granted access to other untrusted domains, without compromising internal domains.
More-complex access lists could be created to try to establish, with finer granularity, which domains are to be accessible or permitted from which other domains, but this requires extensive management which at best is quite error-prone for the end user and easily opens holes in a firewall that do not directly hurt the user who reconfigured his browser to try to access some external service but hurts the owners of other services behind the firewall.

### Signed Scripts

A certain degree of additional trust may be lent to a script by having the author digitally sign it. But signed scripts have not really caught on as they require certificates do not change the basic problem that some completely-unknown party has written a script that might now have access to internal resources.

### Asking the User

Where the sandbox cannot otherwise determine whether the executing script should be permitted access to the resource, a dialog box may be raised to ask the user to grant special privileges. This is currently permitted for locally-saved scripts and signed scripts. This could be combined with the other options above such as whitelisting, signed scripts, etc. But the big problem with this is that the typical browser user really does not either understand or pay the consequences if he inadvertently opens a hole in his company's firewall. Quite complex settings may be required to permit the user to allow access to desired external services without risking other resources.

## Controlling Resource Access on the Server

Access by untrusted scripts really needs to be under the control of the stake holder, which is the resource and server owner -- not the user -- to determine whether a resource should be insulated from web applications loaded from outside of the firewall.

### Using a SOAP Header for Verification

SOAP messages have a distinct processing model allowing a header to be added that the recipient is required to understand and accept, which identifies the untrusted source of a script making a request. SOAP services which have not been cleared for access by untrusted scripts will reject the requests. This is offered in the Mozilla implementation of SOAP today.
Unfortunately, this does not prevent SOAP messages from being sent to non-SOAP addresses, which is a big enough problem that the verification cannot stand alone to guarantee that untrusted service requests are always properly rejected by services that should be firewall-protected.
It may also be inconvenient to modify a SOAP service to ignore the specific verification header.

### Using a Declarations File

A more robust solution is to rely on getting a file named "`web-scripts-access.xml`" in the root directory of the server that the sandboxed script requests to communicate with. It should be fairly easy for most providers of public resources to create.

## Web Scripts Access Statements

The syntax of statements of the access file are as follows.

    <!ELEMENT webScriptAccess (delegate?|allow*)>
    <!ELEMENT delegate EMPTY>
    <!ELEMENT allow EMPTY>
    <!ATTLIST allow type|from CDATA #IMPLIED>.

### The Root Element

The first element of the file should be the following:
`
<wsa:webScriptAccess xmlns:wsa="http://www.mozilla.org/2002/soap/security`">

### Delegation

If the <`delegate`/> element is present then "`web-scripts-access.xml`" is required in the subdirectory for URIs which are in a subdirectory. For example, if the script in question is "`http://www.example.com/foo/bar.xml`", then the declarations file `http://www.example.com/web-scripts-access.xml` which contains the "`delegate`" keyword delegates to `http://www.example.com/foo/web-scripts-access.xml`. If the URI is in a subdirectory, and the root directory's access file delegated but no access file exists in the subdirectory, then no access is granted. If the root's access file did not delegate, then that access file also handles all resources in subdirectories.
Any syntax error in the document will result in the rest of the file to be ignored. Since the commands only allow access, the order of processing the "`allow`" commands that were successfully parsed is never significant.

### Allowing Web Script Access

To permit scripts to access the resources of this server, use the following command:
`<wsa:allow` ``type="<request-type>" `from` ="<uri-prefix>"/>
The type of request, if specified, will be checked against the type of request being requested by the script, such as ``"`soap`", "`soapv`", or "`load`". Types must not contain spaces. Specify "`any`" as the type to permit any requested type of access to resources.
The principle URI of the script will be checked for the specified URI prefix. If "`from`" is not specified, then all scripts will be allowed. Note: One can also use wild character(s) in "from" value.
For example:
`
<wsa:allow type="soapv" from="http://www.mozilla.org"/>`
This command allows SOAP requests with verification headers from scripts loaded from the domain www.mozilla.org.
`<wsa:allow type="soapv" from="http://*.mozilla.org"/>
` This command allows SOAP requests with verification headers from scripts loaded from the domain with host name containing mozilla.org. That is, http://www.mozilla.org/, http://lxr.mozilla.org, http://komodo.mozilla.org, etc. will be granted access.

## Implementation

nsIWebScriptsAccessService
This interface provides a way to check whether the running script has access to the server that the script wishes to communicate.

- boolean canAccess(in nsIURI aTransportURI, in AString aType);

- aTransportURI - The service URI
- aType - Type requested by the script ( ex. soapv, soap, load, etc. )
- return PR_TRUE if access granted else PR_FALSE

- void invalidateCache(in string aTransportURI);

- Invalidate cached entry for the given transport uri.
- Empty the cache by passing in a empty string

nsWebScriptsAccess ( Implements nsIWebScriptsAccessService)
Maintains access information, for servers, in an access-info-cache ( hashtable ). If an entry was not found in the cache creates one by loading the declaration file ( web-scripts-access.xml ) and extracting information from it ( declaration file ); requested type and subject princple's prefix are compared to the allowed type and prefix in order to determine access. An entry is created if and only if the declaration file is considered valid ( validation based on the syntax described above ); an invalid document will result in access denial. Denies script access in the event of an xml-wellformedness error, or validation error, or if the declaration file does not grant access. Reports errors ( validation, wellformedness, file not found, etc. ) to the console via nsIConsoleService.
Note: Script access is checked via declaration file only if the script security manager denies access.

## Summary

### Advantages

The proposed declaration file places the server operator, not the client in control of access to his server by untrusted scripts. The access hole is no bigger than the service in question. The access is disabled by default, and there is nothing the user needs to do to open access, and nothing that can go wrong to make a hole in his firewall. It seems fairly easy to drop an access file into the root directory of the web server to allow access.

### Delegation with Mixed Ownership

Independent owners of subdirectories cannot grant web script access to these subdirectories without getting the owner of the root directory to post a delegating access file. Normally a server will be either inside or outside of a firewall, so this is not a problem. Where a server spans multiple owners, the alternative would be to scan all directories in the path looking for a web scripts access file, which seems undesirable. On the other hand, perhaps it is not so bad, since it permits independent management in domains where the top level owner may not care about providing access to web services.

### Adjustments

As this new model is applied to SOAP, and potentially document.load or xml-request, it may be desirable to eliminate the same source security bypass, because it is not clear that this is always secure. Other security adjustments may be desired as well.

## Feedback?

Please send me some feedback on this proposal.