Reading the ADsafe widget template, part by part
The ADsafe widget template is short, but every line has a job and the order matters. This walkthrough explains each part using the project's template, its widget structure page and the runtime source.
The overall shape
The template in the source repository has three layers. A page-level script tag loads the runtime, adsafe.js. A container div holds the widget. Inside it, up to three script blocks run in order. The condensed skeleton below is rewritten from the template, with the placeholder text shortened.
<script src="https://your-trusted-host.example/adsafe.js"></script>
<div id="TEMPLATE_">
...markup the widget needs...
<script>
ADSAFE.id("TEMPLATE_");
</script>
<script src="template.js"></script>
<script>
ADSAFE.go("TEMPLATE_", function (dom, lib) {
"use strict";
// widget code
});
</script>
</div>An early archived version of the template advises loading a minified copy of adsafe.js from the site's own trusted domain. The loading line is the host's decision, not the widget author's.
The container and its ids
The widget structure page says the widget must be wrapped in a div with an id made of uppercase ASCII letters and a trailing underscore. Other elements inside may have ids, which must be uppercase and begin with the widget id, so KODA_ allows KODA_BOSANDA. The page builder is responsible for keeping the container id unique on the page, and the DOM page requires that all ids on the page be unique.
The same page requires every input element to carry autocomplete="off". The runtime source also sets that attribute on named elements that guest code creates through the wrapper, and it only lets guest code create tags from a whitelist, which fits the same caution about form data.
ADSAFE.id and library scripts
ADSAFE.id announces which widget is about to load library files. The documentation says it is needed only when the widget uses libraries, and that it may be called only at the top of the widget's first script. In the runtime it records the id and creates an empty library table, and a second call before ADSAFE.go raises an error.
Library files follow their own template, shown here in condensed form:
ADSAFE.lib("name", function (lib) {
"use strict";
return {
// privileged methods
};
});A library registers an object under a name, and the widget later reads it as lib.name. ADSAFE.lib is only valid after ADSAFE.id and before ADSAFE.go; the source rejects it otherwise. The library gets no document access unless the widget passes dom into one of its methods. The script tags for libraries must sit at the top level of the container, and their URLs are expected to be ones the site has approved.
ADSAFE.go and what it does
ADSAFE.go takes the container id and a callback. The page must call it once, from an inline script, as the last script block in the fragment. The id must match the one given to ADSAFE.id. The documentation says the verifier can check these placement rules statically.
- The runtime looks up the container element and checks that it is a
div. - It removes the script elements inside the container, since they have already run, and raises an error if there were none.
- It wraps the container as the
domobject. - It calls any interceptors registered through
ADSAFE._intercept, giving the page a chance to add, remove or change methods. - It calls the widget callback with
domandlib, catching and logging any error, then drops its references.
The widget structure page gives an example interceptor that wraps the style method of the bunch prototype so that setting position: absolute throws, as a guard against phishing-style overlays.
The static check and the limits of the template
Two JSLint option sets appear in the documentation: {adsafe: true, fragment: true} for a widget and {adsafe: true, fragment: false} for a library file. The template is a convention that only works when that check has actually been run on the code between the tags.
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. The runtime source is dated 2017 in its header and relies on browser behaviour from its own period, so reading the template is useful for study rather than as a recipe. Continue with the widget structure page, the sample widgets, or a small mediated DOM example.
Primary sources
- ADsafe template.html in the source repository
- ADsafe source repository (adsafe.js, README)
- Widget Structure page, 2008 archive capture
Related guides
Independent educational explanation. Read alongside the cited sources; this page does not certify the historical runtime as a current security boundary.
