** JavaScript Security: Past, Present, and Future Concerns
Table of Contents
Background
Security issue like rogue HTML, malicious JavaScript, and XSS have
been employed since before 1995.
There were a number of issues related to core JavaScript exploits that
came about with the increased use of JavaScript for Ajax in addition
to the release of MSIE6 (see issues with arguments, eval, try/catch)
Issues relating to Ajax and history mining1 go back to 2006.
Much of the security work done on JavaScript was performed in 2007 and
2008 and the tools from that era reflect that work (limiting global
scope changes, binding of valueOf(), etc.) The primary concern here
is that the analysis performed for the implementations at that time
haven’t been updated to reflect current browsers.
The context for concerns about exploits has also changed: while in
2004 ads were directly injected into site contents most major sites
have moved toward iframed deployments. The counter to this is for
third-party widgets: limited access should be provided.
Exploits in the wild
“This example illustrates that library designers do not expect their
functions to be called with untrusted arguments. This trust assumption
is currently valid, as evidenced by the lack of actual exploits
against Twitter, but becomes invalid when hosting ADsafe-verified
advertisements.” 2
Confirming asset integrity
Verifying correctness via ad hoc review
“One reason why prior work has not focussed on verifying correctness
of APIs is because present JavaScript, based on the 3rd edition of
ECMA-262 standard, is not amenable to static analysis, for reasons
discussed in section 2.” 3
Worst case on compromise (DNS or host)
Lack of data execution
Communicate between frames / sandboxes
“Web browsers provide a platform for web applications. These
applications rely on the browser to isolate frames from different
security origins and to provide secure inter-frame communication.” 4
Nomenclature
security enforcing JavaScript
host
The site being viewed by a user that has JavaScript not created by
resources
FBJS
A sub-set of JavaScript designed to run in a hosted container on
Facebook.
secure mashup problem
“Safely displaying third-party advertisements is a special
case of the more general secure mashup problem in which
an integrator (e.g., a publisher) attempts to interact with a
collection of untrusted gadgets (e.g., advertisements).”
http://www.adambarth.com/papers/2010/finifter-weinberger-barth.pdf
dynamic enforcers
Unlike static verifiers, dynamic enforcers transform the source program
by inserting a number of run-time security checks.
statically verify containment
unvetted objects
The unvetted objects are the JavaScript objects that are not
accessible by the guest script on the empty page. For example, all the
objects created by the host page are unvetted because those objects
are not present on the empty page. As another example, the document
object is unvetted because it is not accessible by the guest script on
the empty page, even though document exists on the empty page.5
CORS
JSONP
Tools
Tool | Feature | Notes | URL |
ADsafe | static analysis | blacklist properties | http://www.adsafe.org/ |
Blancura | static analysis | whitelist properties | http://webblaze.cs.berkeley.edu/2010/blancura/ |
Caja | dynamic analysis | ||
Closure Compiler | lint | type annotations | |
Cuckoo | malware | n/a | http://www.cuckoobox.org/ |
Dojo Secure | static analysis | blacklist | |
DoctorJS | indexing | ||
Esmorph | https://github.com/ariya/esmorph | ||
Esprima | ast | ||
FBJS | transpiler | ||
Jacaranda | static analysis | ||
JSLint | lint | ||
Cover | https://github.com/itay/node-cover | ||
parse-js | ast | ||
Web Sandbox | dynamic? | http://www.websandbox-code.org/ |
ADsafe adsafe
www.adsafe.org/
Making JavaScript Safe for Advertising. JavaScript, the programming
ADsafe makes it safe to put guest code (such as third party scripted
advertising or widgets) on a web page.
Name | Description |
create(object) | Create a new empty object that inherits from object. |
get(object, name) | Get the value of the object’s name property. |
go(id, function) | Start the widget. The id string must match the id of the widget’s div. |
has(object, name) | true if the object has an own proerty with that name. |
id(id) | Identify the widget. The id string must match the id of the widget’s div. |
isArray(value) | Returns true if the value is an array. |
later(function, milliseconds) | Call a function in the future. |
lib(name, function) | Register an ADsafe library. |
log(string) | Post the string to the browser’s log. |
remove(object, name) | Remove a property from the object. |
set(object, name, value) | Set a property’s value on the object. |
Crockford compared Caja to ADsafe in
Further analysis of the system is available6 as well as general
research on JavaScript core semantics and a verifier for JSLint (+ADsafe)7
Caja caja
GlobalObjectPoisoning
http://code.google.com/p/google-caja/wiki/GlobalObjectPoisoning
Should be possible, even with only manual review, to ensure we don’t
modify any of the host environment objects.
EvalArbitraryCodeExecution
http://code.google.com/p/google-caja/wiki/EvalArbitraryCodeExecution
Shouldn’t be using eval or new Function() to bypass creation.
CrossScopeParameterModification
http://code.google.com/p/google-caja/wiki/CrossScopeParameterModification
It’s unlikely that we would need to be providing an assignment to the
arguments object. Also, most of the validation checks wouldn’t allow
for this anyway.
ScriptInHtml
http://code.google.com/p/google-caja/wiki/ScriptInHtml
This is a fairly general problem if we use a sink system for
attempting to clean the data. May need to work with an implementation
team to determine what they consider appropriate to push into the DOM.
InnerHtmlYieldsCdata
http://code.google.com/p/google-caja/wiki/InnerHtmlYieldsCdata
Would be trivial to show a team that we don’t use any of the
workarounds with the deprecated elements:
listing
plaintext
xmp
DomAllowsXsrf
http://code.google.com/p/google-caja/wiki/DomAllowsXsrf
Without using Caja it’s difficult to prove that a library doesn’t
perform these actions.
DomAllowsKeylogging
http://code.google.com/p/google-caja/wiki/DomAllowsKeylogging
Would need to prove that we don’t have key events handled by the
system. Would need to do further review on the static implementation.
RedirectWithoutUserAction
http://code.google.com/p/google-caja/wiki/RedirectWithoutUserAction
Bypassing the same-origin policy:
“The same-origin policy is a sweeping security restriction on what web
content JavaScript code can interact with. It typically comes into
play when a web page includes <iframe> elements or opens other browser
windows. In this case, the same-origin policy governs the interactions
of JavaScript code in one window or frame with the content of other
windows and frames. Specifically, a script can read only the
properties of windows and documents that have the same origin as the
document that contains the script…”
GlobalScopeViaThis
http://code.google.com/p/google-caja/wiki/GlobalScopeViaThis
This would need to be something checked via static analysis.
DeleteUnmasksGlobals
http://code.google.com/p/google-caja/wiki/DeleteUnmasksGlobals
Audit for the use of delete.
GATEKEEPER8 gatekeeper
with
arguments
setTimeout
setInterval
eval
apply
call
Function
document.write
.innerHTML
CORS
The followning is just pulled from wikipedia:
CORS is supported by all browsers based on the following layout engines:
Gecko 1.9.1 (Firefox 3.5, SeaMonkey 2.0) and above.
WebKit (Initial revision uncertain, Safari 4 and above, Google Chrome 3 and above, possibly earlier)
MSHTML/Trident 4.0 (Internet Explorer 8) provides partial support via the XDomainRequest object.
The following browsers are also noteworthy in their lack of CORS support:
No Presto-based browser implements CORS, as of Opera 11.6, Opera Mobile 11.1, and Opera Mini 6.0. Support is expected in version 12.7
Camino does not implement CORS in the 2.0.x release series because these versions are based on Gecko 1.9.0.
As of version 0.10.2, Arora exposes WebKit’s CORS-related APIs, but
attempted cross-origin requests will fail.
Tasks
Define a secure subset of JavaScript
This would need to be done with tools like Esprima or parse-js unless
existing tools should be used.
Manually look for globals, constructor
A manual check should be performed for global pollution.
This is based on “3.1 Containment Architecture”
http://www.adambarth.com/papers/2010/finifter-weinberger-barth.pdf
Define the success criteria for external vendors
Ad code is often shifted out by the ad networks which makes is a
higher threat to a page.
Define tainted values in the system
A generic suite of test data should be provided to ensure that the
system, when writing out data, doesn’t allow for an exploit.
Create tools matrix
TODO Evaluate: ADsafe
This is largely just about the process of using JSLint as a validation
step since this is all a validation process.
TODO Evaluate: Dojo Secure
Evaluate: Jacaranda
Tooling: instrumentation tools
Reading
Language-Based Isolation of Untrusted JavaScript adsafe
Preventing Capability Leaks in Secure JavaScript Subsets
Publishers wish to sandbox third-party advertisements
to protect themselves from malicious advertisements. One
promising approach, used by ADsafe, Dojo Secure, and
Jacaranda, sandboxes advertisements by statically verifying that their
JavaScript conforms to a safe subset of the language.
Footnotes:
B. Contaiment-friendly JavaScript http://www-cs-students.stanford.edu/~ataly/Papers/sp11.pdf