There is just one tiny problem: The users found a way to fight back! Almost all modern browsers now come with popup suppression enabled by default, support the blocking of cookies or have plugins like Adblock or Ghostery to fully cleanse the website from any type of tracking or advertising. And it seems to work, as a recent campaign by various german online publishers reveals. These publishers asked their readers to disable the adblocking software, arguing they would cause more harm than good and result in serious losses of income.
Feedback to that campaign was, as to be expected, mixed. Many people explained they merely use adblocking as a means of self defense: adverts, they said, were too aggressive in color, distracting, badly placed or too fat for mobile devices on a low bandwidth connection. Quite valid reasons to my taste – and even the publishers admitted they made sense. A shockingly small amount of people replied that they do not explicitly block ads, but merely do not allow JavaScript to be executed by default; and, as a side-effect, are killing pretty much all those tags that require JavaScript to adjust the HTML DOM within the browser to display the ad or do the statistical tracking.
So why would those users – originally being only a relatively small group anyway – disable JavaScript? The easy answer would be to simply name them paranoid geeks. But then, as another side-effect of the campaign, adblock plugin downloads doubled or even tripled during said campaign, and donations to the developers went up too. So maybe some of the people are just fed up with commercials taking over their browser, and the lack of privacy because of all the tracking and data mining? Or perhaps, the truth is that they are – like me to some extent – paranoid enough to not trust these ads to execute JavaScript (or worse, fire up the Flash plugin). Because, what many don't know is that ad serving is quite often a recursive process: While the webmaster may have only embedded the ad-tag from his adserver of choice, the actual content delivered may have been served by a completely unrelated machine to download additional code from or after the spot on the website had been re-sold various times. The latter happens because, in case there is no current booking for a slot, an adserver is not expected to deliver a blank image, but merely fall back to some other ad used instead.
While this might still create some small revenue for the website owner, the recursive lookup of hostnames as well as downloads of additional JavaScript and media files is quite a performance drain for the enduser's device. And it reduces the trustworthiness of the actual content, as nobody can really tell where the script has come from by the time it made its way to the browser. So even if the company running the adserver you are embedding into your website can claim – hopefully correctly – that their servers are safe, they hardly have any say in the content they deliver.
A related – though not necessarily obvious – problem is the actual embedding of the ad tag. While it simply won't work with JavaScript disabled on the browser level, there are some other technical issues as well. People claim the fact that the XML version of HTML (aka XHTML) was not exactly successful in terms of market share as well as browser support is partly related to the way advertisements had to be embedded into websites. Most services require adding a <script>
element into the <head>
section of the document as well as an inline function call wherever an ad should appear on the page. What seems convenient from a development perspective, however, is technically a really bad choice: First of all, inline scripting makes assumptions on how the browser is processing the html, and secondly it forces the browser to stop the parsing of the markup and switch into executing JavaScript – just to switch back to parsing afterwards. The problem is, when using an XML-Parser rather than an SGML-Parser, many things JavaScript allows for, like document.write(), cannot be used and thus do not work. As a result, the inline script might not work as expected, or even not be executed at all.
Back in the days when XHTML was defined, the adserver companies at first ignored these problems, telling everyone who complained to switch back to HTML 4 or force the browser into compat- or quirksmode to stop it from using the XML parser. After a while, instead of fixing the real problem – the use of inline scripting – the adserver vendors merely changed the scriptcode to work without the problematic functions, making it work in HTML and XHTML variants. And while I guess it seems like a "good enough" solution at first, I already back than was waiting for the problem to return. And, voila, in 2013 the problem is back.
In an attempt to block XSS (Cross Site Scripting) attacks from being successful, Mozilla, Apple and Google implemented a new security mechanism named Content Security Policy, abbreviated CSP, into their respective browsers. The idea behind the CSP is simple but highly effective: Only allow external JavaScript sources from whitelisted domains (individually defined by the webmaster) and disable all inline scripting. Assuming an attacker won't be able to alter the list of allowed domains at the same time as he's injecting code into the content, it would no longer be possible to inject active scripting into the HTML.
While that approach is technically fixing the XSS issues on the wrong end, it feels a bit like self-defense again: Since the backend developers obviously fail at escaping the output properly – despite the fact that XSS is decades old and every developer should know how to protect his or her website – the browser seems to be the last line of defense.
Of course, as with pretty much all solutions that try to fix things at the wrong place, the protection won't be 100%: I can come up with multiple ways to work around these "limitations" already and I bet the bad guys will come up with even more in almost no time. But at least the adserver vendors are going to be forced to finally fix their adtags to work without inline scripting and without downloading additional code from unknown sources. Better than nothing.