CVE-2022-46162: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: discourse-bbcode is the official BBCode plugin for Discourse. Prior to commit 91478f5, CSS injection can occur when rendering content generated with the discourse-bccode plugin. This vulnerability only affects sites which have the discourse-bbcode plugin installed and enabled. This issue is patched in commit 91478f5. As a workaround, ensure that the Content Security Policy is enabled and monitor any posts that contain bbcode.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 9.8
Published: 2022-11-30T23:15Z
Repository: https://github.com/discourse/discourse-bbcode
Language: JavaScript
Files changed: assets/javascripts/lib/discourse-markdown/bbcode.js, spec/pretty_text_spec.rb
Commit date: 2022-11-30 11:22:30 -0700
Commit message: SECURITY: Fix allowed font names (#41)

Limit the allowed names for fonts and added some tests.
Diff: diff --git a/assets/javascripts/lib/discourse-markdown/bbcode.js b/assets/javascripts/lib/discourse-markdown/bbcode.js
index 9887c7e..10d34da 100644
--- a/assets/javascripts/lib/discourse-markdown/bbcode.js
+++ b/assets/javascripts/lib/discourse-markdown/bbcode.js
@@ -200,11 +200,11 @@ export function setup(helper) {
   ]);
 
   helper.allowList({
     custom(tag, name, value) {
       if (tag === "span" && name === "style") {
-        return /^(font-size:(xx-small|x-small|small|medium|large|x-large|xx-large|[0-9]{1,3}%)|background-color:#?[a-zA-Z0-9]+|color:#?[a-zA-Z0-9]+|font-family:[\s\S]+)$/.exec(
+        return /^(font-size:(xx-small|x-small|small|medium|large|x-large|xx-large|[0-9]{1,3}%)|background-color:#?[a-zA-Z0-9]+|color:#?[a-zA-Z0-9]+|font-family:'[a-zA-Z0-9\s-]+')$/.exec(
           value
         );
       }
 
       if (tag === "div" && name === "style") {
diff --git a/spec/pretty_text_spec.rb b/spec/pretty_text_spec.rb
index 71e8599..839d79e 100644
--- a/spec/pretty_text_spec.rb
+++ b/spec/pretty_text_spec.rb
@@ -23,10 +23,31 @@ describe PrettyText do
     html = '<p>hello <span style="font-family:\'usa\'">usa</span> text</p>'
 
     expect(cooked).to eq(html)
   end
 
+  it 'can apply font bbcode with hyphen' do
+    cooked = PrettyText.cook "hello [font=sans-serif]sans-serif[/font] text"
+    html = '<p>hello <span style="font-family:\'sans-serif\'">sans-serif</span> text</p>'
+
+    expect(cooked).to eq(html)
+  end
+
+  it 'can apply font bbcode with space' do
+    cooked = PrettyText.cook "hello [font=Times New Roman]Times New Roman[/font] text"
+    html = '<p>hello <span style="font-family:\'Times New Roman\'">Times New Roman</span> text</p>'
+
+    expect(cooked).to eq(html)
+  end
+
+  it 'only uses fonts with valid text' do
+    cooked = PrettyText.cook "hello [font=ui-monospace';]usa[/font] text"
+    html = '<p>hello <span>usa</span> text</p>'
+
+    expect(cooked).to eq(html)
+  end
+
   it 'can apply small bbcode' do
     cooked = PrettyText.cook "hello [small]usa[/small] text"
     html = '<p>hello <span style="font-size:x-small">usa</span> text</p>'
 
     expect(cooked).to eq(html)

Vulnerable code:         return /^(font-size:(xx-small|x-small|small|medium|large|x-large|xx-large|[0-9]{1,3}%)|background-color:#?[a-zA-Z0-9]+|color:#?[a-zA-Z0-9]+|font-family:[\s\S]+)$/.exec(
Fixed code:         return /^(font-size:(xx-small|x-small|small|medium|large|x-large|xx-large|[0-9]{1,3}%)|background-color:#?[a-zA-Z0-9]+|color:#?[a-zA-Z0-9]+|font-family:'[a-zA-Z0-9\s-]+')$/.exec(
  it 'can apply font bbcode with hyphen' do
    cooked = PrettyText.cook "hello [font=sans-serif]sans-serif[/font] text"
    html = '<p>hello <span style="font-family:\'sans-serif\'">sans-serif</span> text</p>'

    expect(cooked).to eq(html)
  end

  it 'can apply font bbcode with space' do
    cooked = PrettyText.cook "hello [font=Times New Roman]Times New Roman[/font] text"
    html = '<p>hello <span style="font-family:\'Times New Roman\'">Times New Roman</span> text</p>'

    expect(cooked).to eq(html)
  end

  it 'only uses fonts with valid text' do
    cooked = PrettyText.cook "hello [font=ui-monospace';]usa[/font] text"
    html = '<p>hello <span>usa</span> text</p>'

    expect(cooked).to eq(html)
  end