Cookie Stuffing: Stuff you `set-cookie`

Phil Dobson
4 min readSep 13, 2019

--

Cookie stuffing (or dropping) is a simple yet fiendishly clever attack that can be used to siphon money from an unsuspecting affiliate or refer a friend scheme. And most of the time, the people getting stuffed (the good citizens of the web like you and I) aren’t any the wiser. But what is it? And how can the companies running these affiliate schemes stop it in its tracks?

Who’s stuffing what now?

Most affiliate and refer a friend programs rely on cookies to track users that are introduced to their website by the third party. Typically, when the customer first enters the website through an affiliate link, a cookie will be set in their browser to mark this. They are free to browse the site at their leisure (or leave and come back), and when they eventually complete a transaction the presence of this cookie links the original introduction back to the affiliate.

Cookie stuffing is the practise of storing cookies in a users browser, without them ever knowingly navigating to the site that set them.

The attackers motive is to extract money from a poorly secured affiliate program. They do this based on the balance of probability that a user who has fallen victim to cookie stuffing may eventually transact with the website the attacker was targeting any way, by their own volition. If they do - they’ll be paid for an introduction that didn’t happen willingly or knowingly.

Cookie stuffing is a ‘black hat’ form of marketing. Content producing websites may drop cookies as a subtle mechanism to supplement their revenue. But far more commonly, cookies are stuffed maliciously through compromised websites.

How are they doing this?

Browsers may make HTTP requests to websites other than the one being visited for numerous reasons. These ‘cross-origin’ requests are typically originated by a script, or other basic elements of html: <img>, <link>, <iframe> and so on. What may be surprising about these is two things:

  1. Any request may result in cookies being stored. Even an <img> request.
  2. It doesn’t matter if the source for an html element points to a resource that doesn’t match semantically. If an <img> source points to something other than an image, sure it won’t render — but cookies may still be set.

Someone including or injecting<img src=”http://super-big-retailer.com/affiliate/cookie-stuffing-joe” /> in a page might result in a pay day for cookie stuffing Joe without you ever knowing.

How can websites protect their customers?

It’s possible to entirely prevent cookies from being stuffed by changing the response of an affiliate endpoint to activate security features built right in to all of the modern browsers. These mechanisms are:

  • CORS (Cross-Origin Resource Sharing)

Restrict other domains from dropping cookies through ajax requests by ensuring that the Access-Control-Allow-Origin header is set to only domains you trust. This won’t protect against cross origin requests spawned from html tags such as <img> unfortunately, as regardless of whether they flout your CORS policy the cookies will still be set. Nor does it solve the issue of people rendering the link in an iframe.

  • Iframe rendering block

Adding the response headers Content-Security-Policy: frame-ancestors none and X-Frame-Options: sameorigin (for backward compatibility) will prevent an iframe from being rendered on another domain. The key word being rendered — cookies will still be set as a result of the request made by an iframe, regardless of whether it renders or not. The solution is therefore to stop using set-cookie as the mechanism for setting cookies altogether, and instead ensure they are only set on render — i.e. move them to a script.

Here is an example demonstrating what could be returned from an affiliate endpoint. Given appropriate CORS protection, this would entirely prevent the cookie from being stuffed unknowingly into a users browser. It simply sets the cookie, and redirects the user to a place of your choice.

<html>
<head>
<script>
document.cookie = "affiliate=a-non-cookie-stuffer;expires=2019-01-01T00:00:00Z;path=/";
location.replace("https://my-super-great-website.com");
</script>
</head>
</html>

Server side attack detection

Unfortunately there is no deterministic way to detect cookie stuffing attacks on the server side. Requests originating from a user genuinely browsing to a page will explicitly contain ‘text/html’ in the ‘Accept’ header in all major browsers, where requests from <img> tags will not. Unfortunately using iframes or newer browser features such as <link rel=prerender> (especially in the absence of some browsers supporting transactional cookie stores) make this an ineffective control.

--

--

Phil Dobson

Software engineer living in the sunny South of England.