diff --git a/src/Symfony/Component/AssetMapper/ImportMap/ImportMapRenderer.php b/src/Symfony/Component/AssetMapper/ImportMap/ImportMapRenderer.php index e8ad69953cf1c..65957f74e4fd9 100644 --- a/src/Symfony/Component/AssetMapper/ImportMap/ImportMapRenderer.php +++ b/src/Symfony/Component/AssetMapper/ImportMap/ImportMapRenderer.php @@ -27,7 +27,9 @@ */ class ImportMapRenderer { - private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL = 'https://ga.jspm.io/npm:es-module-shims@1.8.0/dist/es-module-shims.js'; + // https://generator.jspm.io/#S2NnYGAIzSvJLMlJTWEAAMYOgCAOAA + private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL = 'https://ga.jspm.io/npm:es-module-shims@1.8.2/dist/es-module-shims.js'; + private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_INTEGRITY = 'sha384-+dzlBT6NPToF0UZu7ZUA6ehxHY8h/TxJOZxzNXKhFD+5He5Hbex+0AIOiSsEaokw'; public function __construct( private readonly ImportMapGenerator $importMapGenerator, @@ -47,7 +49,7 @@ public function render(string|array $entryPoint, array $attributes = []): string $importMap = []; $modulePreloads = []; $cssLinks = []; - $polyFillPath = null; + $polyfillPath = null; foreach ($importMapData as $importName => $data) { $path = $data['path']; @@ -58,7 +60,7 @@ public function render(string|array $entryPoint, array $attributes = []): string // if this represents the polyfill, hide it from the import map if ($importName === $this->polyfillImportName) { - $polyFillPath = $path; + $polyfillPath = $path; continue; } @@ -102,22 +104,31 @@ public function render(string|array $entryPoint, array $attributes = []): string HTML; - if (false !== $this->polyfillImportName && null === $polyFillPath) { + if (false !== $this->polyfillImportName && null === $polyfillPath) { if ('es-module-shims' !== $this->polyfillImportName) { throw new \InvalidArgumentException(sprintf('The JavaScript module polyfill was not found in your import map. Either disable the polyfill or run "php bin/console importmap:require "%s"" to install it.', $this->polyfillImportName)); } // a fallback for the default polyfill in case it's not in the importmap - $polyFillPath = self::DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL; + $polyfillPath = self::DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL; } - if ($polyFillPath) { - $url = $this->escapeAttributeValue($polyFillPath); + if ($polyfillPath) { + $url = $this->escapeAttributeValue($polyfillPath); + $polyfillAttributes = $scriptAttributes; + + // Add security attributes for the default polyfill hosted on jspm.io + if (self::DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL === $polyfillPath) { + $polyfillAttributes = $this->createAttributesString([ + 'crossorigin' => 'anonymous', + 'integrity' => self::DEFAULT_ES_MODULE_SHIMS_POLYFILL_INTEGRITY, + ] + $attributes); + } $output .= << - + HTML; } diff --git a/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapRendererTest.php b/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapRendererTest.php index 76a855bf91a1b..0ff4d4069c7d3 100644 --- a/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapRendererTest.php +++ b/src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapRendererTest.php @@ -121,6 +121,7 @@ public function testDefaultPolyfillUsedIfNotInImportmap() ); $html = $renderer->render(['app']); $this->assertStringContainsString('