Magento 2.4.7: CSP restrict mode im Checkout - Probleme mit Inline Skripten
Nach dem Update auf Magento 2.4.7 funktioniert der Checkout auf einmal nicht mehr. Die Search Console zeigt folgende Fehlermeldung an:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline' 'unsafe-eval'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.
Das Problem liegt an der neuen Content Security Policy (CSP) im restrict mode. Dieser Modus ist seit Magento 2.4.7 im Checkout standardmäßig aktiviert und verhindert das Laden von Inline-Skripten, die nicht authorisiert wurden.
Ein Inline-Skript ist ein Skript, das direkt im HTML-Code eingebettet ist. Zum Beispiel fügt ein Modul dieses direkt im phtml-File ein:
<script>
require([
'jquery',
], function ($) {
// Skript
});
</script>
Es gibt nun 2 Möglichkeiten, das Problem zu lösen:
1. Inline-Skript in separate JS-Datei auslagern
Das Inline-Skript wird in eine separate JS-Datei ausgelagert und über das requireJS-Modul geladen: https://developer.adobe.com/commerce/frontend-core/javascript/requirejs/
Dies ist die bevorzugt Methode und war es auch schon vor dem Setzen des restrict mode.
Treten die oben genannten Fehlermeldung für Inline-Skripte nach dem Update auf 2.4.7 auf, so gab es vermutlich eigenen Grund diese als Inline-Skript einzubinden. Daher möchte ich hier auf die zweite Möglichkeit näher eingehen:
2. Inline-Skript mit nonce-Attribut
Das nonce-Attribut kann dem script-Tag hinzugefügt und über den CSP-Header autorisiert werden.
MAgento 2.4.7 hat bereits einen Helper integriert, der diese Funktionalität bereitstellt. Das obige Beispiel muss nun wie folgt angepasst werden:
<?php
$scriptString = "require([
'jquery',
], function ($) {
// Skript
});";
/**
* @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer
*/
echo /* @noEscape */ $secureRenderer->renderTag('script', [], $scriptString, false);
In der Ausgabe wird dem script-Tag das nonce-Attribut hinzugefügt und im content-security-policy-Header aufgenommen:
<script nonce="NmV0ZmI0bjl6bDA3ajd4MzVwODM3NzA0czV3d3c4cXM=">
require([
'jquery',
], function ($) {
// Skript
});
</script>
Neben der Fehlermeldung in der Developer Console im Browser sieht man die jeweilige Zeilennummer in der der Fehler auftritt. So kann der betreffende Code schnell aufgefunden werden und alle Inline-Skripte entsprechend angepasst werden.
Detaillierte Informationen zum Nonce-Attribute finden sich in der MDN: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce