Skip to content

Commit e132fd5

Browse files
lulalalagjtorikian
authored andcommitted
Fix XSS vulnerability on table of content generation
1 parent 2b34ff9 commit e132fd5

File tree

3 files changed

+11
-2
lines changed

3 files changed

+11
-2
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ gem 'rouge'
186186
* `PlainTextInputFilter` - `escape_utils`
187187
* `SanitizationFilter` - `sanitize`
188188
* `SyntaxHighlightFilter` - `rouge`
189+
* `TableOfContentsFilter` - `escape_utils`
189190
* `TextileFilter` - `RedCloth`
190191

191192
_Note:_ See [Gemfile](/Gemfile) `:test` block for version requirements.

lib/html/pipeline/toc_filter.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
HTML::Pipeline.require_dependency('escape_utils', 'TableOfContentsFilter')
2+
13
module HTML
24
class Pipeline
35
# HTML filter that adds an 'id' attribute to all headers
@@ -43,7 +45,7 @@ def call
4345
uniq = headers[id] > 0 ? "-#{headers[id]}" : ''
4446
headers[id] += 1
4547
if header_content = node.children.first
46-
result[:toc] << %(<li><a href="##{id}#{uniq}">#{text}</a></li>\n)
48+
result[:toc] << %(<li><a href="##{id}#{uniq}">#{EscapeUtils.escape_html(text)}</a></li>\n)
4749
header_content.add_previous_sibling(%(<a id="#{id}#{uniq}" class="anchor" href="##{id}#{uniq}" aria-hidden="true">#{anchor_icon}</a>))
4850
end
4951
end

test/html/pipeline/toc_filter_test.rb

+7-1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ def test_all_header_tags_are_found_when_adding_anchors
9292
assert_equal 6, doc.search('a').size
9393
end
9494

95+
def test_toc_outputs_escaped_html
96+
@orig = %(<h1>&lt;img src="x" onerror="alert(42)"&gt;</h1>)
97+
98+
refute_includes toc, %(<img src="x" onerror="alert(42)">)
99+
end
100+
95101
def test_toc_is_complete
96102
@orig = %(<h1>"Funky President" by James Brown</h1>
97103
<h2>"It's My Thing" by Marva Whitney</h2>
@@ -101,7 +107,7 @@ def test_toc_is_complete
101107
<h6>"Ruthless Villain" by Eazy-E</h6>
102108
<h7>"Be Thankful for What You Got" by William DeVaughn</h7>)
103109

104-
expected = %(<ul class="section-nav">\n<li><a href="#funky-president-by-james-brown">"Funky President" by James Brown</a></li>\n<li><a href="#its-my-thing-by-marva-whitney">"It's My Thing" by Marva Whitney</a></li>\n<li><a href="#boogie-back-by-roy-ayers">"Boogie Back" by Roy Ayers</a></li>\n<li><a href="#feel-good-by-fancy">"Feel Good" by Fancy</a></li>\n<li><a href="#funky-drummer-by-james-brown">"Funky Drummer" by James Brown</a></li>\n<li><a href="#ruthless-villain-by-eazy-e">"Ruthless Villain" by Eazy-E</a></li>\n</ul>)
110+
expected = %(<ul class="section-nav">\n<li><a href="#funky-president-by-james-brown">&quot;Funky President&quot; by James Brown</a></li>\n<li><a href="#its-my-thing-by-marva-whitney">&quot;It&#39;s My Thing&quot; by Marva Whitney</a></li>\n<li><a href="#boogie-back-by-roy-ayers">&quot;Boogie Back&quot; by Roy Ayers</a></li>\n<li><a href="#feel-good-by-fancy">&quot;Feel Good&quot; by Fancy</a></li>\n<li><a href="#funky-drummer-by-james-brown">&quot;Funky Drummer&quot; by James Brown</a></li>\n<li><a href="#ruthless-villain-by-eazy-e">&quot;Ruthless Villain&quot; by Eazy-E</a></li>\n</ul>)
105111

106112
assert_equal expected, toc
107113
end

0 commit comments

Comments
 (0)