Skip to content

Commit 9d1c9e2

Browse files
committed
fix source dedup breaking with port wildcards
1 parent 5f91c40 commit 9d1c9e2

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

lib/secure_headers/headers/content_security_policy.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,10 @@ def reject_all_values_if_none(source_list)
154154
# e.g. *.github.jpy.wang asdf.github.com becomes *.github.jpy.wang
155155
def dedup_source_list(sources)
156156
sources = sources.uniq
157-
wild_sources = sources.select { |source| source =~ STAR_REGEXP }
157+
wild_sources = sources.select { |source| source =~ DOMAIN_WILDCARD_REGEX }
158158

159159
if wild_sources.any?
160-
schemes = sources.map { |source| [source, URI(source).scheme] }.to_h
160+
schemes = sources.map { |source| [source, source_scheme(source)] }.to_h
161161
sources.reject do |source|
162162
!wild_sources.include?(source) &&
163163
wild_sources.any? { |pattern| schemes[pattern] == schemes[source] && File.fnmatch(pattern, source) }
@@ -212,5 +212,9 @@ def strip_source_schemes(source_list)
212212
def symbol_to_hyphen_case(sym)
213213
sym.to_s.tr("_", "-")
214214
end
215+
216+
def source_scheme(source)
217+
URI(source.sub(PORT_WILDCARD_REGEX, '')).scheme
218+
end
215219
end
216220
end

lib/secure_headers/headers/policy_management.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ def self.included(base)
152152

153153
FETCH_SOURCES = ALL_DIRECTIVES - NON_FETCH_SOURCES - NON_SOURCE_LIST_SOURCES
154154

155-
STAR_REGEXP = Regexp.new(Regexp.escape(STAR))
155+
DOMAIN_WILDCARD_REGEX = /(?<=\A|[^:])\*/
156+
PORT_WILDCARD_REGEX = /:\*/
156157
HTTP_SCHEME_REGEX = %r{\Ahttps?://}
157158

158159
WILDCARD_SOURCES = [

spec/lib/secure_headers/headers/content_security_policy_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ module SecureHeaders
5656
expect(csp.value).to eq("default-src *.example.org")
5757
end
5858

59+
it "allows for port wildcards" do
60+
csp = ContentSecurityPolicy.new(connect_src: %w(ws://localhost:*))
61+
expect(csp.value).to eq("connect-src ws://localhost:*")
62+
end
63+
5964
it "removes http/s schemes from hosts" do
6065
csp = ContentSecurityPolicy.new(default_src: %w(https://example.org))
6166
expect(csp.value).to eq("default-src example.org")

0 commit comments

Comments
 (0)