Only allow RFC conformant protocol schemes

This commit is contained in:
Oliver Günther
2025-03-31 14:06:19 +02:00
parent 936a5edb23
commit 4a706db8e8
4 changed files with 21 additions and 3 deletions
@@ -32,7 +32,9 @@ module Admin::Settings
def settings_params
super.tap do |settings|
settings["allowed_link_protocols"] = settings["allowed_link_protocols"].split(/\r?\n/)
settings["allowed_link_protocols"] = settings["allowed_link_protocols"]
.split(/\r?\n/)
.map { |protocol| protocol.strip.downcase.gsub(/[^a-z0-9+\-.]+/, "") }
end
end
@@ -106,7 +106,7 @@ export class CKEditorSetupService {
const allowedLinkProtocols = this.configurationService.allowedLinkProtocols;
if (allowedLinkProtocols) {
config.link = { allowedProtocols: allowedLinkProtocols };
config.link = { allowedProtocols: allowedLinkProtocols.map((el:string) => _.escapeRegExp(el)) };
}
return config;
@@ -45,9 +45,15 @@ module OpenProject::TextFormatting
# Skip text nodes that are within preformatted or linked blocks
SKIPPED_BLOCKS = %w(pre code kbd a).to_set
def self.protocols
Setting
.allowed_link_protocols
.map { |protocol| Regexp.escape(protocol) }
end
# Match custom schemes and ignore trailing punctuation
def self.regexp
%r{((?:#{Setting.allowed_link_protocols.join('|')}):/?/?[^\s<\u00A0"]*[^\s<\u00A0",;\.])}i
%r{((?:#{protocols.join('|')}):/?/?[^\s<\u00A0"]*[^\s<\u00A0",;\.])}i
end
def call
@@ -57,5 +57,15 @@ RSpec.describe "Allowed link protocols", :js do
expect(Setting.allowed_link_protocols).to match_array(custom_protocols)
expect(Setting::AllowedLinkProtocols.all).to include(*custom_protocols)
expect(Setting::AllowedLinkProtocols.all).to include(*always_allowed_protocols)
scroll_to_element find_by_id("settings_allowed_link_protocols")
custom_protocols = %w[http+ssh f[oa]x]
find_by_id("settings_allowed_link_protocols").set(custom_protocols.join("\n"))
click_on "Save"
expect(page).to have_text I18n.t(:notice_successful_update)
RequestStore.clear!
expect(Setting.allowed_link_protocols).to contain_exactly("http+ssh", "foax")
end
end