tech blog

AppNexus is today’s most powerful, open, and customizable ad tech platform. Advertising’s largest and most innovative companies build their businesses on AppNexus.

XSS Vulnerability and Patch Explained

| Comments

Last week a security researcher, Randy Westergren, pointed out in a blog post a vulnerability from cross-site scripting (XSS) that was common across our industry and impacted AppNexus. We’ve since rolled out a patch to the immediate issue and encourage you to read Brian’s blogpost addressing this and publisher security in the broader context.

We also decided to prepare a more detailed technical view of the issues identified by Randy Westergren to share with our customers and partners. The identified vulnerability is different from malware threats where the main delivery mechanism is javascript called by a specific creative, an area we invest significant resources to prevent and fight. And when we look around the internet, we still see this XSS vulnerability through code owned by a number of other companies. We plan to reach out to these companies to notify them of this vulnerability and hopefully encourage a widespread fix across our industry.

To begin, let’s start with hash marks ( # ), which in a URL or HTML code are called “anchors” and they serve as a placeholder in the content or application, allowing for easy navigation to preset points in the page. They’re also common in single page web applications to call new content. When a URL containing the hash mark character is requested from the website, it’s common for the entire page to be loaded normally with no reference or record of the hash mark sent to the web server.

The particular style of attack in the blogpost is called a cross-site vulnerability because it can often traverse multiple websites. In the context of ad-serving, a majority of advertisements are served from different web servers than those that serve the content of the site itself. In a technical sense, these ads are “cross-site” advertisements. If the advertisements are replaced with malicious objects, they become “cross-site scripting attacks”, or “XSS attacks”.

When the website calls for an advertisement via an HTTP request to another computer, the referrer URL is often passed to the remote computer as a parameter. For example, if a publisher is monetizing their inventory using an AppNexus tag, the tag may run the following javascript to get the ad onto the page:

1
document.write('<script src="https://3rdpartyadserver.com?referrerurl=https://example.com"></script>');

Bad actors who use the internet for criminal activity are often looking for ways to get their code onto a legitimate website. One way to potentially do this would be leveraging a weakness in the use of hash marks and how common adserving is done. A bad actor could create a URL such as the following and then try to get users to click to this location:

1
https://example.com#'bad-javascript'

Where bad-javascript is code that the bad actor wants executed in the web browser of the users machine. When clicked, the user would be taken to the real example.com homepage and everything after the hash mark would not be sent to the website’s server, which would prevent server-side protections from functioning. However, our JavaScript written to the HTML becomes the following, and note how the single quotes of the referer URL break the string being written to page:

1
document.write('<script src="https://3rdpartyadserver.com?referrerurl=https://example.com#' bad-javascript '"></script>');

This example is very similar to the live examples shown by Randy Westergren in how a custom URL after the hash mark can escape the JavaScript and execute code on page (in this case, a simple alert box).

Since the page that loads looks like (and is) the page that the user intended to visit, the user would be more likely to disregard pop-up dialog boxes, install “plug-ins” or “updates” if asked, or complete other risky behavior. Or worse, a more sophisticated attack could have javascript that steals user credentials/information as the user fills out form fields.

One approach to sanitize this JavaScript exploit is to truncate any JavaScript escape characters, removing any part of the URL after the characters ( ‘ ), ( “ ), or ( \ ). This approach gave us an immediate patch with minimal breakage to our current integrations. We have rolled out this fix to truncate these special characters that may break the string being written to page. This customization of the referrer URL will prevent this bad-javascript from running. Here’s an example that shows the change in a live environment.

The first ad on this page asks AppNexus for the referrer URL unencoded, which we modify to return a truncated version. The second ad asks for the referrer URL encoded.

Another technique to prevent this escaping is to always encode the referrer URL that’s returned. We actually offer this option to our clients today (as the second ad in the example above shows), but some clients elect to have the un-encoded version returned for certain use cases. Looking forward, we plan to fully deprecate the un-encoded version of our macro and ask that our clients and partners convert to supporting a referrer URL that’s always encoded. This change should help further drive adoption of other companies and further minimize risk to users across the Internet.

Comments