Adyen has the following recommendations on how to comply with the PCI DSS requirements 6.4.3 and 11.6.1. If they are applicable to your integration, follow the instructions we provide.
If you are eligible for Self-Assessment Questionnaire A (SAQ A), you are exempt from these requirements.
When creating these guidelines, Adyen considered implementations advised by the PCI Security Standards Council (PCI SSC) in their formal guidance document: Payment Page Security and Preventing E-Skimming - Guidance for PCI DSS Requirements 6.4.3 and 11.6.1.
Authorize and assure the integrity of scripts for PCI DSS requirement 6.4.3
We recommend that you implement a Content Security Policy (CSP) on your payment page, because it allows you to authorize scripts before loading them on your page.
You can modify the CSP in your page header to do the following:
- Allow all internally-loaded scripts by default.
- Expressly allow scripts from non-internal domains to be loaded.
Additionally, we provide guidance on the options for reporting and alerting from your implemented CSP.
To ensure the integrity of scripts, we recommend implementing Subresource Integrity (SRI) to confirm that the files you load from Adyen have not been manipulated or tampered with by malicious actors.
Build your CSP
Following our guidance to build your CSP.
Start with a report-only CSP HTTP header.
This type of header causes no issues with how your integration works because it does not block any resources from loading.
By using the Content-Security-Policy-Report-Only
header instead of the Content-Security-Policy
header, the browser only logs the violation. It does not block any content from being loaded.
Add the following HTTP header to your page.
Content-Security-Policy-Report-Only: default-src 'self'; font-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'
After you implement it, you can see the violations that show up when visiting your website. The report-only policy shows you the following.
Field | Description | |
---|---|---|
default-src |
This CSP directive tells the browser which domains or subdomains scripts may be loaded from. In all of our examples, we use 'self' as a trusted source, telling the browser to only load resources that are hosted on the same domain or subdomain. If sources are not defined in any other directives, they apply this default policy. |
|
font-src |
What fonts may be loaded. | |
img-src |
What images may be loaded. | |
script-src |
What scripts may be loaded. | |
style-src |
What styles/css may be loaded. |
Allow scripts and iframes from external sources
Your CSP header can allow either of the following:
- Anything, like images, scripts, media, and more, to be loaded from an external domain or subdomain.
- Only things that you specify to be loaded from an external domain or subdomain.
We recommend that you implement the following blocking policy.
-
Change the header to
Content-Security-Policy
. This is a blocking policy. You can add some defined exemptions. -
Allow specific domains and subdomains. When you define specific sources for scripts (
script-src
) and iframes (frame-src
) they only allow loading resources from the specified domains, and everything else is blocked.For Adyen integrations, we recommend that you apply the following CSP configuration:
Recommended CSP configurationExpand viewCopy link to code blockCopy codeContent-Security-Policy: default-src 'self'; script-src: *.adyen.com pay.google.com *.payments-amazon.com *.paypal.com *.ratepay.com *.cash.app font-src: cash-f.squarecdn.com style-src: *.cash.app frame-src: * img-src: * connect-src:* form-action:* If you have other third party integrations loading additional scripts, you must explicitly add them to the
script-src
directive.
Scripts and images that are loaded from other domains violate this policy and are included in the report that you configure for the CSP.
We suggest that you use the wildcard (
- Adyen loads only 3D Secure (3DS) authentication iframes. According to the PCI SSC, the 3DS script validation process is exempted from the scope of PCI DSS Requirement 6.4.3, because the trust relationship with the 3DS service provider is established through due diligence, onboarding, and business agreements of the entities involved. Because it is not possible to list all issuer domains loading iframes for 3DS authentication, a more stringent CSP might block 3DS iframes from loading.
- Not using any
frame-src
definition might be functional but not stable. It would lead the CSP to use the default value, which is usually defined as blocking none. Therefore, some definition needs to be made. With our recommended CSP header setup, we make it possible to use CSP, but still allow loading all 3DS iframes which are exempted from the requirements. -
This recommended implementation could allow any iframes to be loaded. However, iframes from Adyen are sandboxed and iframes that come from 3DS issuer banks are also sandboxed. By sandboxing, issues such as cross-site scripting are prevented, not adding any additional risk.
Web Browser Sandboxing allows running web applications in isolation to prevent browser-based malware from spreading to the rest of the webpage or network. Most modern browsers already have a sandbox by default to enhance the protection of the user's computer.
Create an inventory of scripts
Following PCI DSS Requirement 6.4.3, all scripts added to your page must be in an inventory. This means that you must keep a list, including the ones required for Adyen integrations, with the business reason to use them.
Furthermore, you must have a simple periodical authorization sign-off. Ensuring that all scripts have been explicitly authorized reduces the risk of unnecessary scripts being added to the payment page without appropriate approval. However, for some cases, it can be impractical for such authorization to occur before a script is changed or a new script is loaded to the page. In these cases, the authorization should be confirmed as soon as a change is reported.
Adyen loads scripts from the following domain sources. Include them in your inventory for your Adyen integration:
Source | Description |
---|---|
*.adyen.com | Adyen-authorized domain for scripts loaded for payment-processing-associated services. |
pay.google.com | Allows integration with the Google Pay payment method. |
*.payments-amazon.com | Allows integration with the Amazon Pay payment method. |
*.paypal.com | Allows integration with the PayPal payment method. |
*.ratepay.com | Allows integration with the Ratepay payment method. |
*.cash.app | Allows integration with the Cash App service. |
Check the integrity of scripts
We recommend implementing Subresource Integrity (SRI) to ensure that the files you load from Adyen have not been manipulated or tampered with by malicious actors. Use the SRI hash by doing the following.
- To the
<script>
or<link>
elements, add theintegrity
attribute. -
Add the
crossorigin
attribute. Browsers also check to ensure that the origin allows Cross-Origin Resource Sharing (CORS). If the browser detects that the file's hash does not match the specified hash, the browser does not load the resource. Find out which browsers support SRI.For each version of Adyen Web Drop-in/Components, we provide the SRI hashes that you include as the
integrity
attribute for the JavaScript and CSS files. In the release notes, go to the Updating to this version section for the version that you use.The following example shows how include SRI hashes for the
adyen.js
andadyen.css
resources for v5.59.1:SRI hashes for v5.59.1Expand viewCopy link to code blockCopy code<script src="https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/5.59.0/adyen.js" integrity="sha384-O8p0CLZyOw1jkmYN7ZwJxWzd+sDYRFGpLEffqc+dKye24gFImbU72did4PC7ysTY" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/5.59.0/adyen.css" integrity="sha384-zgFNrGzbwuX5qJLys75cOUIGru/BoEzhGMyC07I3OSdHqXuhUfoDPVG03G+61oF4" crossorigin="anonymous">
Implement change and tamper detection mechanisms to comply with PCI DSS Requirement 11.6.1
A functional CSP implementation can provide authorization and alerting in case of attempts to introduce unknown scripts or changes to currently authorized scripts. These events are considered valid alerts and "indicators of compromise", for the purpose of requirement 11.6.1.
You must collect all CSP alerts in a practical manner. This can be done by implementing the report-to
directive, which sends you a report of alerts. This can help to meet the requirements included in 11.6.1, such as "alerting personnel of unauthorized modification".
-
Create an endpoint on your server you want the browser to use for reporting CSP violations. If a CSP violation occurs, a report is generated. It contains a serialized CSPViolationReportBody object instance. Using the mechanisms of the Reporting API, the browser sends the report to your endpoint URL.
-
Specify the mapping between endpoint names and URLs by adding the
Reporting-Endpoints
response header to your CSP. You can use any name for your endpoints.Example of Reporting-Endpoints response headerExpand viewCopy link to code blockCopy codeReporting-Endpoints: your_endpoint_name="https://example.com/csp-reports"
-
Add
report-to
, specifying the endpoint URL on your server that you want the browser to use for reporting CSP violations.Example of report-to directiveExpand viewCopy link to code blockCopy codereport-to your_endpoint_name
-
When a CSP violation occurs, you get a report with CSP violations.