Why eval, this and global names are restricted in guest code
A language-subset sandbox works by removing every way for guest code to reach the real global object or the real DOM. Each rule in ADsafe's list closes one such route, and reading them together shows how much surface a normal JavaScript program has.
The goal of the list
The ADsafe home page says a script in a page has intimate access to the page's information and relationships, and that ADsafe removes language features that are unsafe or grant uncontrolled access to browser components. The idea is an object-capability model: guest code can only use references the host hands it. Anything that lets code obtain a reference it was not given, notably window and document, has to go.
The rules below are taken from the project's documentation and the adsafe.js source. The explanations of each risk are checked against MDN.
eval and its relatives
The ADsafe page states that eval provides access to the global object. MDN adds that eval() runs its argument with the privileges of the caller, and that direct eval can read and change local variables in the calling scope. Indirect eval runs in the global scope. Either way, a string chosen by the guest becomes code that static analysis never saw, which defeats a checker that only reads source text.
The same reasoning covers the Function constructor. A short check in any JavaScript engine shows the route:
var f = function () {};
var key = "constructor";
f[key]("return globalThis")(); // returns the global objectThis is why the subset bans the name constructor and non-literal subscripts as well as eval itself. A Content Security Policy without 'unsafe-eval' would also block this string-to-code call, according to MDN's CSP guide, which lists the Function() constructor next to eval(). The two controls overlap, but a policy is set by the host, while the subset is a property of the guest code.
this and global names
ADsafe's text says that when a method is called as a function, this is bound to the global object, so the subset prohibits this in guest code. MDN confirms that in non-strict code a function called with an undefined this receives globalThis. Strict mode removes that substitution, and ADsafe's templates do use "use strict", but banning this outright is simpler to verify than proving each call site safe.
Global variables are restricted for the same reason. A guest that can name document needs no further help. ADsafe allows limited use of Array, Boolean, Number, String and Math, plus ADSAFE and any globals a site designates. It also restricts Date and Math.random, which the documentation says is to make widget behaviour easier to determine.
Property names, arguments and with
- Banned names. The
adsafe.jssource listsarguments,callee,caller,constructor,eval,prototype,stack,unwatch,valueOfandwatch. Names that start or end with an underscore are also rejected, because some browsers had dangerous properties with those shapes. - Subscripts. The documentation disallows
a[i]unless the subscript is a literal or an expression that must produce a number, because the checker cannot prove thatiis not a dangerous name. Guest code usesADSAFE.getandADSAFE.set, which check the name at run time. - arguments. The
argumentspseudo-array is disallowed. MDN now recommends rest parameters over it in modern code. - with. The statement changes the scope chain, which the ADsafe page says makes static analysis impossible. MDN says
withis forbidden in strict mode.
What the rules cannot cover
These rules are a static filter plus a small runtime. They assume the checker implements every rule, that the host page does not hand out an unsafe object, and that built-in prototypes have not been modified. The ADsafe documentation itself lists such conditions: for example, prototypes of built-in types must not be extended in ways that breach containment, and untrusted code can indirectly invoke the page's window.onerror handler, which therefore must be written carefully.
Browsers have also changed since the project was written. New language features and APIs appear regularly, and a subset defined before them cannot be assumed to account for them.
ADsafe is a historic project. This site is an independent reference, is not the official ADsafe site, and is not endorsed by the author of ADsafe. It does not offer ADsafe as a currently reviewed security boundary. Related reading: building a mediated DOM interface, and the original DOM interface notes.
Primary sources
- ADsafe home page and README in the source repository
- adsafe.js source (banned names, ADSAFE.get and set)
- MDN: eval()
- MDN: this
Related guides
Independent educational explanation. Read alongside the cited sources; this page does not certify the historical runtime as a current security boundary.
