80 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# 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 }
 | 
						|
          },
 | 
						|
          audio: {
 | 
						|
            doc: HTML::Pipeline.parse("<audio><source src='#{scheme}alert(1);'></audio>"),
 | 
						|
            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
 |