Skip to content
代码片段 群组 项目
未验证 提交 bc1c2f10 编辑于 作者: Brett Walker's avatar Brett Walker 提交者: GitLab
浏览文件

Apply 1 suggestion(s) to 1 file(s)

上级 de710e6b
No related branches found
No related tags found
无相关合并请求
显示
83 个添加20 个删除
......@@ -15,8 +15,6 @@ class BaseSanitizationFilter < HTML::Pipeline::SanitizationFilter
include Gitlab::Utils::StrongMemoize
extend Gitlab::Utils::SanitizeNodeLink
RENDER_TIMEOUT = 5.seconds
UNSAFE_PROTOCOLS = %w[data javascript vbscript].freeze
def call
......@@ -57,9 +55,8 @@ def allowlist
allowlist[:attributes]['img'].push('data-diagram-src')
# Allow any protocol in `a` elements
# and then remove links with unsafe protocols
# and then remove links with unsafe protocols in SanitizeLinkFilter
allowlist[:protocols].delete('a')
allowlist[:transformers].push(self.class.method(:sanitize_unsafe_links))
# Remove `rel` attribute from `a` elements
allowlist[:transformers].push(self.class.remove_rel)
......
......@@ -2,10 +2,10 @@
module Banzai
module Filter
# HTML Filter to modify the attributes of external links
# HTML Filter to modify the attributes of external links.
# This is considered a sanitization filter.
class ExternalLinkFilter < HTML::Pipeline::Filter
prepend Concerns::TimeoutFilterHandler
prepend Concerns::PipelineTimingCheck
SCHEMES = ['http', 'https', nil].freeze
RTLO = "\u202E"
......@@ -46,7 +46,7 @@ def render_timeout
# partial un-sanitized results.
# It's ok to allow any following filters to run since this is safe HTML.
def returned_timeout_value
HTML::Pipeline.parse(COMPLEX_MARKDOWN_MESSAGE)
HTML::Pipeline.parse(Banzai::Filter::SanitizeLinkFilter::TIMEOUT_MARKDOWN_MESSAGE)
end
# if this is a link to a proxied image, then `src` is already the correct
......
......@@ -77,6 +77,7 @@ def process_tag(tag)
def sanitized_content_tag(name, content, options = {})
html = content_tag(name, content, options)
node = Banzai::Filter::SanitizationFilter.new(html).call
node = Banzai::Filter::SanitizeLinkFilter.new(node).call
node&.children&.first
end
......
......@@ -10,8 +10,6 @@ class AbstractReferenceFilter < ReferenceFilter
prepend Concerns::TimeoutFilterHandler
prepend Concerns::PipelineTimingCheck
RENDER_TIMEOUT = 2.seconds
def initialize(doc, context = nil, result = nil)
super
......
# frozen_string_literal: true
module Banzai
module Filter
# Validate links and remove unsafe protocols.
# This can be intensive, so it was split from BaseSanitizationFilter in order
# for it to have its own time period.
class SanitizeLinkFilter < HTML::Pipeline::Filter
prepend Concerns::TimeoutFilterHandler
include Gitlab::Utils::SanitizeNodeLink
# [href], [src], [data-src], [data-canonical-src]
CSS = Gitlab::Utils::SanitizeNodeLink::ATTRS_TO_SANITIZE.map { |x| "[#{x}]" }.join(', ')
XPATH = Gitlab::Utils::Nokogiri.css_to_xpath(CSS).freeze
TIMEOUT_MARKDOWN_MESSAGE =
<<~HTML
<p>Timeout while sanitizing links - rendering aborted. Please reduce the number of links if possible.</p>
HTML
def call
doc.xpath(self.class::XPATH).each do |el|
sanitize_unsafe_links({ node: el })
end
doc
end
private
def render_timeout
SANITIZATION_RENDER_TIMEOUT
end
# If sanitization times out, we can not return partial un-sanitized results.
# It's ok to allow any following filters to run since this is safe HTML.
def returned_timeout_value
HTML::Pipeline.parse(TIMEOUT_MARKDOWN_MESSAGE)
end
end
end
end
......@@ -17,8 +17,8 @@ module Filter
# This is a small extension to the CommonMark spec. If they start allowing
# spaces in urls, we could then remove this filter.
#
# Note: Filter::SanitizationFilter should always be run sometime after this filter
# to prevent XSS attacks
# Note: Filter::SanitizationFilter/Filter::SanitizeLinkFilter should always be run sometime
# after this filter to prevent XSS attacks
#
class SpacedLinkFilter < HTML::Pipeline::Filter
prepend Concerns::PipelineTimingCheck
......
......@@ -6,6 +6,7 @@ class AsciiDocPipeline < BasePipeline
def self.filters
FilterArray[
Filter::AsciiDocSanitizationFilter,
Filter::SanitizeLinkFilter,
Filter::CodeLanguageFilter,
Filter::GollumTagsFilter,
Filter::WikiLinkGollumFilter,
......
......@@ -8,6 +8,7 @@ def self.filters
Filter::BlockquoteFenceLegacyFilter,
Filter::MarkdownFilter,
Filter::BroadcastMessageSanitizationFilter,
Filter::SanitizeLinkFilter,
Filter::EmojiFilter,
Filter::ColorFilter,
Filter::AutolinkFilter,
......
......@@ -9,6 +9,7 @@ def self.filters
@filters ||= FilterArray[
Filter::HtmlEntityFilter,
Filter::SanitizationFilter,
Filter::SanitizeLinkFilter,
Filter::EmojiFilter
]
end
......
......@@ -13,9 +13,10 @@ def self.filters
@filters ||= FilterArray[
Filter::CodeLanguageFilter,
Filter::PlantumlFilter,
# Must always be before the SanitizationFilter to prevent XSS attacks
# Must always be before the SanitizationFilter/SanitizeLinkFilter to prevent XSS attacks
Filter::SpacedLinkFilter,
Filter::SanitizationFilter,
Filter::SanitizeLinkFilter,
Filter::EscapedCharFilter,
Filter::KrokiFilter,
Filter::GollumTagsFilter,
......
......@@ -12,6 +12,7 @@ def self.filters
@filters ||= FilterArray[
*super,
Filter::SanitizationFilter,
Filter::SanitizeLinkFilter,
*Banzai::Pipeline::GfmPipeline.reference_filters,
Filter::EmojiFilter,
Filter::ExternalLinkFilter,
......
......@@ -6,6 +6,7 @@ class LabelPipeline < BasePipeline
def self.filters
@filters ||= FilterArray[
Filter::SanitizationFilter,
Filter::SanitizeLinkFilter,
Filter::References::LabelReferenceFilter
]
end
......
......@@ -6,6 +6,7 @@ class MarkupPipeline < BasePipeline
def self.filters
@filters ||= FilterArray[
Filter::SanitizationFilter,
Filter::SanitizeLinkFilter,
Filter::CodeLanguageFilter,
Filter::AssetProxyFilter,
Filter::ExternalLinkFilter,
......
......@@ -7,6 +7,7 @@ def self.filters
@filters ||= FilterArray[
Filter::HtmlEntityFilter,
Filter::SanitizationFilter,
Filter::SanitizeLinkFilter,
Filter::AssetProxyFilter,
Filter::EmojiFilter,
Filter::CustomEmojiFilter,
......
......@@ -8,9 +8,6 @@
it_behaves_like 'default allowlist'
describe 'custom allowlist' do
it_behaves_like 'XSS prevention'
it_behaves_like 'sanitize link'
subject { filter(exp).to_html }
context 'allows `a` elements' do
......
......@@ -210,10 +210,11 @@
end
end
it_behaves_like 'pipeline timing check'
it_behaves_like 'does not use pipeline timing check'
it_behaves_like 'a filter timeout' do
let(:text) { 'text' }
let(:expected_result) { described_class::COMPLEX_MARKDOWN_MESSAGE }
let(:expected_result) { Banzai::Filter::SanitizeLinkFilter::TIMEOUT_MARKDOWN_MESSAGE }
let(:expected_timeout) { described_class::SANITIZATION_RENDER_TIMEOUT }
end
end
......@@ -314,6 +314,7 @@ def legacy_pipeline_filter(text, context = {})
doc = Banzai::Pipeline::PlainMarkdownPipeline.call(doc[:output], context)
doc = Banzai::Filter::CodeLanguageFilter.call(doc[:output], context, nil)
doc = Banzai::Filter::SanitizationFilter.call(doc, context, nil)
doc = Banzai::Filter::SanitizeLinkFilter.call(doc, context, nil)
filter(doc, context)
end
......
......@@ -8,9 +8,6 @@
it_behaves_like 'default allowlist'
describe 'custom allowlist' do
it_behaves_like 'XSS prevention'
it_behaves_like 'sanitize link'
it 'customizes the allowlist only once' do
instance = described_class.new('Foo')
control_count = instance.allowlist[:transformers].size
......@@ -224,6 +221,8 @@
end
end
it_behaves_like 'does not use pipeline timing check'
it_behaves_like 'a filter timeout' do
let(:text) { 'text' }
let(:expected_result) { described_class::COMPLEX_MARKDOWN_MESSAGE }
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Banzai::Filter::SanitizeLinkFilter, feature_category: :team_planning do
include FilterSpecHelper
it_behaves_like 'XSS prevention'
it_behaves_like 'sanitize link'
it_behaves_like 'does not use pipeline timing check'
it_behaves_like 'a filter timeout' do
let(:text) { 'text' }
let(:expected_result) { described_class::TIMEOUT_MARKDOWN_MESSAGE }
let(:expected_timeout) { described_class::SANITIZATION_RENDER_TIMEOUT }
end
end
......@@ -12,6 +12,8 @@
subject { described_class.to_html(exp, project: project) }
it_behaves_like 'sanitize pipeline'
context "allows `a` elements" do
let(:exp) { "<a>Link</a>" }
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册