Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
603fa7c1
Commit
603fa7c1
authored
Jan 31, 2018
by
Douwe Maan
Committed by
Robert Speicher
Feb 09, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge branch 'fix-mermaid-xss' into 'security-10-4'
[10.4] Fix stored XSS in code blocks
parent
5e9e5692
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
130 additions
and
15 deletions
+130
-15
app/assets/javascripts/render_mermaid.js
app/assets/javascripts/render_mermaid.js
+3
-0
changelogs/unreleased/fix-stored-xss-in-code-blocks.yml
changelogs/unreleased/fix-stored-xss-in-code-blocks.yml
+5
-0
lib/banzai/filter/syntax_highlight_filter.rb
lib/banzai/filter/syntax_highlight_filter.rb
+22
-12
spec/features/markdown/copy_as_gfm_spec.rb
spec/features/markdown/copy_as_gfm_spec.rb
+0
-0
spec/features/markdown/gitlab_flavored_markdown_spec.rb
spec/features/markdown/gitlab_flavored_markdown_spec.rb
+0
-0
spec/features/markdown/markdown_spec.rb
spec/features/markdown/markdown_spec.rb
+0
-0
spec/features/markdown/math_spec.rb
spec/features/markdown/math_spec.rb
+22
-0
spec/features/markdown/mermaid_spec.rb
spec/features/markdown/mermaid_spec.rb
+24
-0
spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+54
-3
No files found.
app/assets/javascripts/render_mermaid.js
View file @
603fa7c1
...
@@ -30,6 +30,9 @@ export default function renderMermaid($els) {
...
@@ -30,6 +30,9 @@ export default function renderMermaid($els) {
$els
.
each
((
i
,
el
)
=>
{
$els
.
each
((
i
,
el
)
=>
{
const
source
=
el
.
textContent
;
const
source
=
el
.
textContent
;
// Remove any extra spans added by the backend syntax highlighting.
Object
.
assign
(
el
,
{
textContent
:
source
});
mermaid
.
init
(
undefined
,
el
,
(
id
)
=>
{
mermaid
.
init
(
undefined
,
el
,
(
id
)
=>
{
const
svg
=
document
.
getElementById
(
id
);
const
svg
=
document
.
getElementById
(
id
);
...
...
changelogs/unreleased/fix-stored-xss-in-code-blocks.yml
0 → 100644
View file @
603fa7c1
---
title
:
Fix stored XSS in code blocks that ignore highlighting
merge_request
:
author
:
type
:
security
lib/banzai/filter/syntax_highlight_filter.rb
View file @
603fa7c1
...
@@ -14,23 +14,33 @@ module Banzai
...
@@ -14,23 +14,33 @@ module Banzai
end
end
def
highlight_node
(
node
)
def
highlight_node
(
node
)
code
=
node
.
text
css_classes
=
'code highlight js-syntax-highlight'
css_classes
=
'code highlight js-syntax-highlight'
language
=
node
.
attr
(
'lang'
)
lang
=
node
.
attr
(
'lang'
)
retried
=
false
if
use_rouge?
(
lang
uage
)
if
use_rouge?
(
lang
)
lexer
=
lexer_for
(
lang
uage
)
lexer
=
lexer_for
(
lang
)
language
=
lexer
.
tag
language
=
lexer
.
tag
else
lexer
=
Rouge
::
Lexers
::
PlainText
.
new
language
=
lang
end
begin
code
=
Rouge
::
Formatters
::
HTMLGitlab
.
format
(
lex
(
lexer
,
node
.
text
),
tag:
language
)
css_classes
<<
"
#{
language
}
"
if
language
rescue
# Gracefully handle syntax highlighter bugs/errors to ensure users can
# still access an issue/comment/etc. First, retry with the plain text
# filter. If that fails, then just skip this entirely, but that would
# be a pretty bad upstream bug.
return
if
retried
begin
language
=
nil
code
=
Rouge
::
Formatters
::
HTMLGitlab
.
format
(
lex
(
lexer
,
code
),
tag:
language
)
lexer
=
Rouge
::
Lexers
::
PlainText
.
new
css_classes
<<
"
#{
language
}
"
retried
=
true
rescue
# Gracefully handle syntax highlighter bugs/errors to ensure
# users can still access an issue/comment/etc.
language
=
nil
retry
end
end
end
highlighted
=
%(<pre class="#{css_classes}" lang="#{language}" v-pre="true"><code>#{code}</code></pre>)
highlighted
=
%(<pre class="#{css_classes}" lang="#{language}" v-pre="true"><code>#{code}</code></pre>)
...
...
spec/features/copy_as_gfm_spec.rb
→
spec/features/
markdown/
copy_as_gfm_spec.rb
View file @
603fa7c1
File moved
spec/features/gitlab_flavored_markdown_spec.rb
→
spec/features/
markdown/
gitlab_flavored_markdown_spec.rb
View file @
603fa7c1
File moved
spec/features/markdown_spec.rb
→
spec/features/markdown
/markdown
_spec.rb
View file @
603fa7c1
File moved
spec/features/markdown/math_spec.rb
0 → 100644
View file @
603fa7c1
require
'spec_helper'
describe
'Math rendering'
,
:js
do
it
'renders inline and display math correctly'
do
description
=
<<~
MATH
This math is inline $`a^2+b^2=c^2`$.
This is on a separate line
```math
a^2+b^2=c^2
```
MATH
project
=
create
(
:project
,
:public
)
issue
=
create
(
:issue
,
project:
project
,
description:
description
)
visit
project_issue_path
(
project
,
issue
)
expect
(
page
).
to
have_selector
(
'.katex .mord.mathit'
,
text:
'b'
)
expect
(
page
).
to
have_selector
(
'.katex-display .mord.mathit'
,
text:
'b'
)
end
end
spec/features/markdown/mermaid_spec.rb
0 → 100644
View file @
603fa7c1
require
'spec_helper'
describe
'Mermaid rendering'
,
:js
do
it
'renders Mermaid diagrams correctly'
do
description
=
<<~
MERMAID
```mermaid
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
```
MERMAID
project
=
create
(
:project
,
:public
)
issue
=
create
(
:issue
,
project:
project
,
description:
description
)
visit
project_issue_path
(
project
,
issue
)
%w[A B C D]
.
each
do
|
label
|
expect
(
page
).
to
have_selector
(
'svg foreignObject'
,
text:
label
)
end
end
end
spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
View file @
603fa7c1
...
@@ -3,35 +3,86 @@ require 'spec_helper'
...
@@ -3,35 +3,86 @@ require 'spec_helper'
describe
Banzai
::
Filter
::
SyntaxHighlightFilter
do
describe
Banzai
::
Filter
::
SyntaxHighlightFilter
do
include
FilterSpecHelper
include
FilterSpecHelper
shared_examples
"XSS prevention"
do
|
lang
|
it
"escapes HTML tags"
do
# This is how a script tag inside a code block is presented to this filter
# after Markdown rendering.
result
=
filter
(
%{<pre lang="#{lang}"><code><script>alert(1)</script></code></pre>}
)
expect
(
result
.
to_html
).
not_to
include
(
"<script>alert(1)</script>"
)
expect
(
result
.
to_html
).
to
include
(
"alert(1)"
)
end
end
context
"when no language is specified"
do
context
"when no language is specified"
do
it
"highlights as plaintext"
do
it
"highlights as plaintext"
do
result
=
filter
(
'<pre><code>def fun end</code></pre>'
)
result
=
filter
(
'<pre><code>def fun end</code></pre>'
)
expect
(
result
.
to_html
).
to
eq
(
'<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre>'
)
expect
(
result
.
to_html
).
to
eq
(
'<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre>'
)
end
end
include_examples
"XSS prevention"
,
""
end
end
context
"when a valid language is specified"
do
context
"when a valid language is specified"
do
it
"highlights as that language"
do
it
"highlights as that language"
do
result
=
filter
(
'<pre><code lang="ruby">def fun end</code></pre>'
)
result
=
filter
(
'<pre><code lang="ruby">def fun end</code></pre>'
)
expect
(
result
.
to_html
).
to
eq
(
'<pre class="code highlight js-syntax-highlight ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre>'
)
expect
(
result
.
to_html
).
to
eq
(
'<pre class="code highlight js-syntax-highlight ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre>'
)
end
end
include_examples
"XSS prevention"
,
"ruby"
end
end
context
"when an invalid language is specified"
do
context
"when an invalid language is specified"
do
it
"highlights as plaintext"
do
it
"highlights as plaintext"
do
result
=
filter
(
'<pre><code lang="gnuplot">This is a test</code></pre>'
)
result
=
filter
(
'<pre><code lang="gnuplot">This is a test</code></pre>'
)
expect
(
result
.
to_html
).
to
eq
(
'<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre>'
)
expect
(
result
.
to_html
).
to
eq
(
'<pre class="code highlight js-syntax-highlight plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre>'
)
end
end
include_examples
"XSS prevention"
,
"gnuplot"
end
end
context
"when Rouge formatting fails"
do
context
"languages that should be passed through"
do
%w(math mermaid plantuml)
.
each
do
|
lang
|
context
"when
#{
lang
}
is specified"
do
it
"highlights as plaintext but with the correct language attribute and class"
do
result
=
filter
(
%{<pre><code lang="#{lang}">This is a test</code></pre>}
)
expect
(
result
.
to_html
).
to
eq
(
%{<pre class="code highlight js-syntax-highlight #{lang}" lang="#{lang}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>}
)
end
include_examples
"XSS prevention"
,
lang
end
end
end
context
"when Rouge lexing fails"
do
before
do
before
do
allow_any_instance_of
(
Rouge
::
Formatter
).
to
receive
(
:format
).
and_raise
(
StandardError
)
allow_any_instance_of
(
Rouge
::
Lexers
::
Ruby
).
to
receive
(
:stream_tokens
).
and_raise
(
StandardError
)
end
end
it
"highlights as plaintext"
do
it
"highlights as plaintext"
do
result
=
filter
(
'<pre><code lang="ruby">This is a test</code></pre>'
)
result
=
filter
(
'<pre><code lang="ruby">This is a test</code></pre>'
)
expect
(
result
.
to_html
).
to
eq
(
'<pre class="code highlight js-syntax-highlight" lang="" v-pre="true"><code>This is a test</code></pre>'
)
expect
(
result
.
to_html
).
to
eq
(
'<pre class="code highlight js-syntax-highlight" lang="" v-pre="true"><code><span id="LC1" class="line" lang="">This is a test</span></code></pre>'
)
end
include_examples
"XSS prevention"
,
"ruby"
end
context
"when Rouge lexing fails after a retry"
do
before
do
allow_any_instance_of
(
Rouge
::
Lexers
::
PlainText
).
to
receive
(
:stream_tokens
).
and_raise
(
StandardError
)
end
it
"does not add highlighting classes"
do
result
=
filter
(
'<pre><code>This is a test</code></pre>'
)
expect
(
result
.
to_html
).
to
eq
(
'<pre><code>This is a test</code></pre>'
)
end
end
include_examples
"XSS prevention"
,
"ruby"
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment