diff options
author | Douwe Maan <douwe@gitlab.com> | 2015-11-02 10:49:46 +0000 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2015-11-02 10:49:46 +0000 |
commit | 329e067ff1d235af38f686145b03ced6c1fe7d85 (patch) | |
tree | e14265a4a1237859d698b6ce484174bd45021062 /spec | |
parent | cbd1c3e31e141b26d7c9d72cd36650ed00c2da1d (diff) | |
parent | 16f8ca566b8637dc8092a6b630c23a82a905b437 (diff) | |
download | gitlab-ce-329e067ff1d235af38f686145b03ced6c1fe7d85.tar.gz |
Merge branch 'rs-dev-issue-2613' into 'master'
Add custom protocol whitelisting to SanitizationFilter
Addresses internal https://dev.gitlab.org/gitlab/gitlabhq/issues/2613
We allow any protocol for autolinks: irc://irc.freenode.net/git
But manual Markdown links with the same protocol get sanitized: `[This will not be clickable](irc://irc.freenode.net/git)`: [This will not be clickable](irc://irc.freenode.net/git)
To get around this we have to first allow *all* protocols, and then manually clean dangerous (i.e., `javascript:`) protocols.
See merge request !1496
Diffstat (limited to 'spec')
-rw-r--r-- | spec/lib/gitlab/markdown/sanitization_filter_spec.rb | 101 |
1 files changed, 91 insertions, 10 deletions
diff --git a/spec/lib/gitlab/markdown/sanitization_filter_spec.rb b/spec/lib/gitlab/markdown/sanitization_filter_spec.rb index e50c82d0b3c..27cd00e8054 100644 --- a/spec/lib/gitlab/markdown/sanitization_filter_spec.rb +++ b/spec/lib/gitlab/markdown/sanitization_filter_spec.rb @@ -44,7 +44,7 @@ module Gitlab::Markdown instance = described_class.new('Foo') 3.times { instance.whitelist } - expect(instance.whitelist[:transformers].size).to eq 4 + expect(instance.whitelist[:transformers].size).to eq 5 end it 'allows syntax highlighting' do @@ -77,19 +77,100 @@ module Gitlab::Markdown end it 'removes `rel` attribute from `a` elements' do - doc = filter(%q{<a href="#" rel="nofollow">Link</a>}) + act = %q{<a href="#" rel="nofollow">Link</a>} + exp = %q{<a href="#">Link</a>} - expect(doc.css('a').size).to eq 1 - expect(doc.at_css('a')['href']).to eq '#' - expect(doc.at_css('a')['rel']).to be_nil + expect(filter(act).to_html).to eq exp end - it 'removes script-like `href` attribute from `a` elements' do - html = %q{<a href="javascript:alert('Hi')">Hi</a>} - doc = filter(html) + # Adapted from the Sanitize test suite: http://git.io/vczrM + protocols = { + 'protocol-based JS injection: simple, no spaces' => { + input: '<a href="javascript:alert(\'XSS\');">foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: simple, spaces before' => { + input: '<a href="javascript :alert(\'XSS\');">foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: simple, spaces after' => { + input: '<a href="javascript: alert(\'XSS\');">foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: simple, spaces before and after' => { + input: '<a href="javascript : alert(\'XSS\');">foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: preceding colon' => { + input: '<a href=":javascript:alert(\'XSS\');">foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: UTF-8 encoding' => { + input: '<a href="javascript:">foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: long UTF-8 encoding' => { + input: '<a href="javascript:">foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: long UTF-8 encoding without semicolons' => { + input: '<a href=javascript:alert('XSS')>foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: hex encoding' => { + input: '<a href="javascript:">foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: long hex encoding' => { + input: '<a href="javascript:">foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: hex encoding without semicolons' => { + input: '<a href=javascript:alert('XSS')>foo</a>', + output: '<a>foo</a>' + }, + + 'protocol-based JS injection: null char' => { + input: "<a href=java\0script:alert(\"XSS\")>foo</a>", + output: '<a href="java"></a>' + }, + + 'protocol-based JS injection: spaces and entities' => { + input: '<a href="  javascript:alert(\'XSS\');">foo</a>', + output: '<a href="">foo</a>' + }, + } + + protocols.each do |name, data| + it "handles #{name}" do + doc = filter(data[:input]) + + expect(doc.to_html).to eq data[:output] + end + end + + it 'allows non-standard anchor schemes' do + exp = %q{<a href="irc://irc.freenode.net/git">IRC</a>} + act = filter(exp) + + expect(act.to_html).to eq exp + end + + it 'allows relative links' do + exp = %q{<a href="foo/bar.md">foo/bar.md</a>} + act = filter(exp) - expect(doc.css('a').size).to eq 1 - expect(doc.at_css('a')['href']).to be_nil + expect(act.to_html).to eq exp end end |