summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/utils/sanitize_node_link_spec.rb
blob: 80b0935a7edea2f2f1a2c41b87527899dbd6d0ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# frozen_string_literal: true

require 'spec_helper'

describe Gitlab::Utils::SanitizeNodeLink do
  let(:klass) do
    struct = Struct.new(:value)
    struct.include(described_class)

    struct
  end

  subject(:object) { klass.new(:value) }

  invalid_schemes = [
    "javascript:",
    "JaVaScRiPt:",
    "\u0001java\u0003script:",
    "javascript    :",
    "javascript:    ",
    "javascript    :   ",
    ":javascript:",
    "javascript:",
    "javascript:",
    "   javascript:"
  ]

  invalid_schemes.each do |scheme|
    context "with the scheme: #{scheme}" do
      describe "#remove_unsafe_links" do
        tags = {
          a: {
            doc: HTML::Pipeline.parse("<a href='#{scheme}alert(1);'>foo</a>"),
            attr: "href",
            node_to_check: -> (doc) { doc.children.first }
          },
          img: {
            doc: HTML::Pipeline.parse("<img src='#{scheme}alert(1);'>"),
            attr: "src",
            node_to_check: -> (doc) { doc.children.first }
          },
          video: {
            doc: HTML::Pipeline.parse("<video><source src='#{scheme}alert(1);'></video>"),
            attr: "src",
            node_to_check: -> (doc) { doc.children.first.children.filter("source").first }
          }
        }

        tags.each do |tag, opts|
          context "<#{tag}> tags" do
            it "removes the unsafe link" do
              node = opts[:node_to_check].call(opts[:doc])

              expect { object.remove_unsafe_links({ node: node }, remove_invalid_links: true) }
                .to change { node[opts[:attr]] }

              expect(node[opts[:attr]]).to be_blank
            end
          end
        end
      end

      describe "#safe_protocol?" do
        let(:doc) { HTML::Pipeline.parse("<a href='#{scheme}alert(1);'>foo</a>") }
        let(:node) { doc.children.first }
        let(:uri) { Addressable::URI.parse(node['href'])}

        it "returns false" do
          expect(object.safe_protocol?(scheme)).to be_falsy
        end
      end
    end
  end
end