VYPR
High severityNVD Advisory· Published Feb 18, 2022· Updated Apr 23, 2025

Cross-site Scripting in Prism

CVE-2022-23647

Description

Prism is a syntax highlighting library. Starting with version 1.14.0 and prior to version 1.27.0, Prism's command line plugin can be used by attackers to achieve a cross-site scripting attack. The command line plugin did not properly escape its output, leading to the input text being inserted into the DOM as HTML code. Server-side usage of Prism is not impacted. Websites that do not use the Command Line plugin are also not impacted. This bug has been fixed in v1.27.0. As a workaround, do not use the command line plugin on untrusted inputs, or sanitize all code blocks (remove all HTML code text) from all code blocks that use the command line plugin.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
prismjsnpm
>= 1.14.0, < 1.27.01.27.0

Affected products

1

Patches

1
e002e78c3431

Command Line: Escape markup in command line output (#3341)

https://github.com/PrismJS/prismat055612Feb 16, 2022via ghsa
2 files changed · +4 2
  • plugins/command-line/prism-command-line.js+3 1 modified
    @@ -143,8 +143,10 @@
     		for (var i = 0, l = codeLines.length; i < l; i++) {
     			// Add spans to allow distinction of input/output text for styling
     			if (outputLines.hasOwnProperty(i)) {
    +				// outputLines were removed from codeLines so missed out on escaping
    +				// of markup so do it here.
     				codeLines[i] = '<span class="token output">'
    -					+ outputLines[i] + '</span>';
    +					+ Prism.util.encode(outputLines[i]) + '</span>';
     			} else {
     				codeLines[i] = '<span class="token command">'
     					+ codeLines[i] + '</span>';
    
  • plugins/command-line/prism-command-line.min.js+1 1 modified
    @@ -1 +1 @@
    -!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document){var v=/(?:^|\s)command-line(?:\s|$)/,g="command-line-prompt",p="".startsWith?function(e,t){return e.startsWith(t)}:function(e,t){return 0===e.indexOf(t)},d="".endsWith?function(e,t){return e.endsWith(t)}:function(e,t){var n=e.length;return e.substring(n-t.length,n)===t};Prism.hooks.add("before-highlight",function(e){var t=N(e);if(!t.complete&&e.code){var n=e.element.parentElement;if(n&&/pre/i.test(n.nodeName)&&(v.test(n.className)||v.test(e.element.className))){var a=e.element.querySelector("."+g);a&&a.remove();var i=e.code.split("\n"),r=t.continuationLineIndicies=new Set,s=n.getAttribute("data-continuation-str");if(s&&1<i.length)for(var o=1;o<i.length;o++)i.hasOwnProperty(o-1)&&d(i[o-1],s)&&r.add(o);t.numberOfLines=i.length;var l=t.outputLines=[],m=n.getAttribute("data-output"),u=n.getAttribute("data-filter-output");if(null!==m)m.split(",").forEach(function(e){var t=e.split("-"),n=parseInt(t[0],10),a=2===t.length?parseInt(t[1],10):n;if(!isNaN(n)&&!isNaN(a)){n<1&&(n=1),a>i.length&&(a=i.length),a--;for(var r=--n;r<=a;r++)l[r]=i[r],i[r]=""}});else if(u)for(var c=0;c<i.length;c++)p(i[c],u)&&(l[c]=i[c].slice(u.length),i[c]="");e.code=i.join("\n")}else t.complete=!0}else t.complete=!0}),Prism.hooks.add("before-insert",function(e){var t=N(e);if(!t.complete){for(var n=e.highlightedCode.split("\n"),a=t.outputLines||[],r=0,i=n.length;r<i;r++)a.hasOwnProperty(r)?n[r]='<span class="token output">'+a[r]+"</span>":n[r]='<span class="token command">'+n[r]+"</span>";e.highlightedCode=n.join("\n")}}),Prism.hooks.add("complete",function(e){if(function(e){return"command-line"in(e.vars=e.vars||{})}(e)){var t=N(e);if(!t.complete){var n=e.element.parentElement;v.test(e.element.className)&&(e.element.className=e.element.className.replace(v," ")),v.test(n.className)||(n.className+=" command-line");var a,r="",i=t.numberOfLines||0,s=h("data-prompt","");if(""!==s)a='<span data-prompt="'+s+'"></span>';else a='<span data-user="'+h("data-user","user")+'" data-host="'+h("data-host","localhost")+'"></span>';for(var o=t.continuationLineIndicies||new Set,l='<span data-continuation-prompt="'+h("data-continuation-prompt",">")+'"></span>',m=0;m<i;m++)o.has(m)?r+=l:r+=a;var u=document.createElement("span");u.className=g,u.innerHTML=r;for(var c=t.outputLines||[],p=0,d=c.length;p<d;p++)if(c.hasOwnProperty(p)){var f=u.children[p];f.removeAttribute("data-user"),f.removeAttribute("data-host"),f.removeAttribute("data-prompt")}e.element.insertBefore(u,e.element.firstChild),t.complete=!0}}function h(e,t){return(n.getAttribute(e)||t).replace(/"/g,"&quot")}})}function N(e){var t=e.vars=e.vars||{};return t["command-line"]=t["command-line"]||{}}}();
    \ No newline at end of file
    +!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document){var v=/(?:^|\s)command-line(?:\s|$)/,g="command-line-prompt",p="".startsWith?function(e,t){return e.startsWith(t)}:function(e,t){return 0===e.indexOf(t)},d="".endsWith?function(e,t){return e.endsWith(t)}:function(e,t){var n=e.length;return e.substring(n-t.length,n)===t};Prism.hooks.add("before-highlight",function(e){var t=N(e);if(!t.complete&&e.code){var n=e.element.parentElement;if(n&&/pre/i.test(n.nodeName)&&(v.test(n.className)||v.test(e.element.className))){var a=e.element.querySelector("."+g);a&&a.remove();var i=e.code.split("\n"),r=t.continuationLineIndicies=new Set,s=n.getAttribute("data-continuation-str");if(s&&1<i.length)for(var o=1;o<i.length;o++)i.hasOwnProperty(o-1)&&d(i[o-1],s)&&r.add(o);t.numberOfLines=i.length;var l=t.outputLines=[],m=n.getAttribute("data-output"),u=n.getAttribute("data-filter-output");if(null!==m)m.split(",").forEach(function(e){var t=e.split("-"),n=parseInt(t[0],10),a=2===t.length?parseInt(t[1],10):n;if(!isNaN(n)&&!isNaN(a)){n<1&&(n=1),a>i.length&&(a=i.length),a--;for(var r=--n;r<=a;r++)l[r]=i[r],i[r]=""}});else if(u)for(var c=0;c<i.length;c++)p(i[c],u)&&(l[c]=i[c].slice(u.length),i[c]="");e.code=i.join("\n")}else t.complete=!0}else t.complete=!0}),Prism.hooks.add("before-insert",function(e){var t=N(e);if(!t.complete){for(var n=e.highlightedCode.split("\n"),a=t.outputLines||[],r=0,i=n.length;r<i;r++)a.hasOwnProperty(r)?n[r]='<span class="token output">'+Prism.util.encode(a[r])+"</span>":n[r]='<span class="token command">'+n[r]+"</span>";e.highlightedCode=n.join("\n")}}),Prism.hooks.add("complete",function(e){if(function(e){return"command-line"in(e.vars=e.vars||{})}(e)){var t=N(e);if(!t.complete){var n=e.element.parentElement;v.test(e.element.className)&&(e.element.className=e.element.className.replace(v," ")),v.test(n.className)||(n.className+=" command-line");var a,r="",i=t.numberOfLines||0,s=h("data-prompt","");if(""!==s)a='<span data-prompt="'+s+'"></span>';else a='<span data-user="'+h("data-user","user")+'" data-host="'+h("data-host","localhost")+'"></span>';for(var o=t.continuationLineIndicies||new Set,l='<span data-continuation-prompt="'+h("data-continuation-prompt",">")+'"></span>',m=0;m<i;m++)o.has(m)?r+=l:r+=a;var u=document.createElement("span");u.className=g,u.innerHTML=r;for(var c=t.outputLines||[],p=0,d=c.length;p<d;p++)if(c.hasOwnProperty(p)){var f=u.children[p];f.removeAttribute("data-user"),f.removeAttribute("data-host"),f.removeAttribute("data-prompt")}e.element.insertBefore(u,e.element.firstChild),t.complete=!0}}function h(e,t){return(n.getAttribute(e)||t).replace(/"/g,"&quot")}})}function N(e){var t=e.vars=e.vars||{};return t["command-line"]=t["command-line"]||{}}}();
    \ No newline at end of file
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.