# CSP and PCI Compliance

**The LokiCheckout is developed with the CSP Strict Mode enabled and the policies `unsafe-inline` and `unsafe-eval` removed, making it PCI 4.0+ compliant. However, it does not mean that CSP just works for everything that you would add to your shop. This document explains all.**

## About CSP and Magento
CSP is used by browsers to minimize certain security attacks. It uses HTTP headers to identify a certain policy (reporting mode or restrictive mode) and values that identify certain browser resources that could or could not be used. If you are implementing CSP, security gets tighter but it might also be that specific scripts you are using are no longer usable.

Read more: [developer.mozilla.org/en-US/Web/HTTP/CSP](https://developer.mozilla.org/en-US/Web/HTTP/CSP)

Magento could be tuned to facilitate compliance with PCI DSS v4.4 . This involves two things (to the least):

- Inline scripts are only allowed if they are either accompanied by a `nonce` or if their SHA hash is added to the HTTP headers. This policy requires that `unsafe-inline` is not present in the CSP headers.
- The JavaScript `eval` function - which is used by various libraries like KnockoutJS, jQuery UI, AlpineJS and LivewireJS - is no longer allowed. This policy requires that `unsafe-eval` is not present in the CSP headers.

As you can read, the second point poses a problem, because both Luma and Hyvä do use some of the libraries mentioned above. Because of this, action is required.

## CSP Restrictive Mode in the checkout
Within Magento 2.4.7+ checkout pages, CSP is by default in the restrictive mode. You could disable this again by enabling the reporting mode:

```bash
magerun2 config:store:set csp/mode/storefront_checkout_index_index/report_only 1
```

In this document, we assume that the reporting mode is disabled, so that the restrictive mode is enabled:

```bash
magerun2 config:store:set csp/mode/storefront_checkout_index_index/report_only 0
```

## Inspecting the current headers
By default in Magento, the CSP policies `unsafe-inline` and `unsafe-eval` are added, allowing inline scripts without hashes or nonces, allowing the evil `eval()` function. Because any module is able to override these settings, it is the duty of the webshop maintainer to double-check the current policies. You can inspect the HTTP headers manually in the browser. Or, if you find this harder to read, you might also opt for the [Yireo_CspInspector](https://github.com/yireo/Yireo_CspInspector) module.

```bash
bin/magento csp:inspect:policy script-src
```

## Loki Checkout is CSP-compliant
The good news is that Loki Checkout and its sub-extensions (with a few exceptions - see the known issues below) are compliant with PCI DSS v4, meaning that the code does not depend on `unsafe-inline` or `unsafe-eval`.

Removing the policy `unsafe-inline` is enforced by implementing the additional module [Yireo_CspUtilities](https://github.com/yireo/Yireo_CspUtilities) which is then used by the Loki Checkout extensions to add either a SHA hash to the headers or add a `nonce` to the script tag (whatever you configure in the `Yireo_CspUtilities` module).

Removing the policy `unsafe-eval` is implemented by simply not writing any `eval` code. With vanilla JavaScript, this is pretty evident. Loki Components and Loki Checkout use AlpineJS. To make sure AlpineJS doesn't use `eval` anymore, you need to be using the AlpineJS CSP Build. One way to do this is to enable the `LokiCheckout_Csp` module (see below).

## Enforcing CSP to be PCI DSS v4 compliant
Having a checkout extension that is CSP-compiant is **NOT** enough. First of all, the checkout extension lives within your theme (Luma or Hyvä) which also needs to be CSP-compliant. Second, you need to enable the right CSP policies.

Adding the right policies could be done manually or by adding the `LokiCheckout_Csp` module (see below).

For the theme, the responsibility lies with the theme creator or the agency implementing it - not us, we are merely just an extension vendor.

## Installing the `LokiCheckout_Csp` module
```bash
composer require loki-checkout/magento2-csp
bin/magento module:enable LokiCheckout_Csp
```

When you have enabled this module, there are big chances that in the checkout you are going to see a lot of errors. There is a big chance that these errors actually relate to the theme, not our extension. Normally, you can inspect from which HTML part a specific error originated from. We do this analysis ourselves a lot, to make sure that CSP errors don't occur because of our own extensions.

## CSP with Hyvä themes
For Hyvä, there is a CSP-compliant build of Hyvä (which ships with the AlpineJS CSP Build and upgrades all scripts). Make sure to use this new theme (`Hyva/default-csp`) as the base of your own theme. Currently, a setup of the `Hyva/default-csp` CSP theme plus the `LokiCheckout_Csp` module makes the entire setup CSP-compliant.

[Installing Hyvä CSP Default Theme](https://docs.hyva.io/hyva-themes/writing-code/csp/hyva-default-theme-csp-installation.html)

## CSP with Luma themes
With Luma, the status is unknown. While there is a plugin for KnockoutJS to become CSP-compliant, it is not supported by Adobe. The easiest thing to do here is to remove actually any dependency with KnockoutJS, RequireJS and jQuery on the checkout page. (This is something that will be documented as an experiment by us.)

Fortunately, the LokiCheckout has a trick up its sleeve: Because the LokiCheckout itself supports CSP and because it does not depend on regular Luma JavaScript, you could just remove everything that is unrelated to the checkout and hence, reach CSP compliance. The easiest way to do this is to install the `loki-checkout/magento2-luma-skinny` package.

```bash
composer require loki-checkout/magento2-luma-skinny
bin/magento module:enable LokiCheckout_LumaSkinny
```

This module is just an example (while it works pretty good). Instead of using the module, you could also copy the changes of the module into your own theme.

Note that this is considered somewhat experimental, because the removal of Luma scripts could break extensions that you have installed on top of the checkout. The possible solutions for overcoming those breaking changes are:

- Remove the extensions that break CSP-compliance again;
- Make those extensions compatible with the LokiCheckout;
