Securing Resources from Untrusted Scripts
Behind Firewalls
by
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.
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.
Implementation
nsISOAPSecurityService
This interface implements a method to check whether the running script has
access to the server that the script wishes to communicate.
- boolean checkConnect(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
nsSOAPSecurity ( Implements nsISOAPSecurityService )
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.