JavaScript skimming attacks continue to plague the E-commerce businesses. To combat this threat PCI has introduced new requirements into PCI DSS V4.0 and the new SAQ A and A-EP. One requirement I've been getting asked a lot about is 6.4.3. In this post, I'll show you how you can get started implementing the controls.
PCI DSS 6.4.3 requires organizations to manage all payment page scripts that are loaded and executed in the consumer’s browser, including:
- A method to is implemented to confirm each script is authorized.
- A method is implemented to assure the integrity of each script.
- An inventory of all scripts is maintained with written justification as to why each is necessary.
Integrity and Authorization
The first two points can be tackled using Content Security Policy (CSP) and Subresource Integrity (SRI)
Content Security Policy (CSP): A CSP is a security standard that allows website administrators to specify which sources of content are allowed to be loaded on their website. This can include scripts, images, and other resources. By using a CSP, administrators can ensure that only authorized scripts are loaded on the payment page.
1
2
3
4
5
6
7
8
9
10
11
12
|
<!DOCTYPE html> <html> <head>
<title>My Website</title>
<meta http-equiv= "Content-Security-Policy" content= "script-src 'self';" >
</head>
<body>
<h1>Welcome to My Website</h1>
<p>This is a paragraph of text.</p>
</body>
</html> |
In this example, the Content-Security-Policy
meta tag is added to the <head>
section of the website. The script-src
directive specifies that scripts can only be loaded from the same origin ('self'
). This means that any scripts loaded from other domains, such as the malicious script from https://malicioussite.com/malicious.js
, will be blocked.
Subresource Integrity (SRI) hash: SRI is a security feature that allows website administrators to ensure that a specific version of a script is loaded on their website. To use SRI, administrators generate a cryptographic hash of the script file and include it in the script tag on the payment page. The customer’s browser will then check the hash of the script file against the hash included in the script tag. If they match, the script is considered authorized and will be executed.
1
|
<script src="https://example.com/script.js" integrity="sha256-5rYr5o5IgISVCGwKzZD7HPu8HLd1/W9IuAuXCXy+7K8=" crossorigin="anonymous"></script> |
In this example, the script.js
file is loaded with an integrity
attribute that contains the SHA-256 hash of the file’s content. The browser will calculate the hash of the downloaded file and compare it with the hash specified in the integrity
attribute. If the hashes match, the script is executed. If the hash check fails, the customer’s browser will not execute the script, and an error will be logged in the browser console. This ensures that the JavaScript code has not been modified in transit.
Note: you must ensure the crossorigin="anonymous" attribute is set. Absent a crossorigin attribute, the browser's 'fail-open' choice negates the security benefits of SRI by ignoring the integrity attribute.
Inventory of Scripts
You can find out what scripts are running on a site easily by running the following JavaScript in your developer tools console. The list of scripts will be logged to your console.
javascript:(function() {
var scripts = document.getElementsByTagName("script");
var srcs = [];
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src) {
srcs.push(scripts[i].src);
} else {
srcs.push("inline script");
}
}
console.log(srcs);
})();
Note that this may not show 4th party scripts that these scripts may call, for that you will need to do some extra digging.
A tip for my fellow QSAs out there: you can save this into the URL field of a bookmark to run on any of your customers payment pages with ease.
Alternatively, you can use a browser extension like ScriptSafe, NoScript, or uBlock Origin to show scripts running on a page. These tools offer a much nicer view than what browser development tools will give you.
Once you've got the scripts, don't forget to add them into a register to show your QSA come audit time.
Using a Tool
Since I originally wrote this post there have many companies such as SourceDefense, Feroot, Report URI, Reflectiz, Otto-JS, Jscrambler that have come up with tools to solve this issue and many of these tools also now tackle 11.6.1.
I've had conversations with a few of these vendors and the price range between some of these products was huge.
Most of these tools are agentless, you just need to point them at your payment page, but some would like you to add (even more) JavaScript to the page. The two that have stood out for me would be:
- SourceDefense, which at the time of writing offers users a free solution for a single page and;
- Report URI, which has seemingly very reasonable pricing and boasts the legendary web security blogger and founder of Have I Been Pwned Troy Hunt as one of its Partners.
Conclusion
It is highly recommended that implement Content Security Policy into your ecommerce applications anyway as its an excellent security control with little downside once it has been setup, but many businesses will struggle with maintaining current hashes of third party scripts that Subresource Integrity tags require. Imagine the issues if Stripe, Braintree or Spreedly was to update their iFrame JS if everyone using them had implemented SRI.
The reality is, if you're a Merchant or Service Provider trying to comply with these new requirements, it is likely going to be far easier just to use one of the many tools that are now available than have to manage new releases every time there is a change to a third party script.