Skip to content

Commit a5f7d76

Browse files
committed
refactor and introduce supported directives
1 parent 46764fa commit a5f7d76

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

lib/secure_headers/headers/content_security_policy.rb

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ module Constants
6767
DIRECTIVES_2_0 + DIRECTIVES_DRAFT
6868
).freeze
6969

70-
ALL_DIRECTIVES = DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0 + DIRECTIVES_DRAFT
70+
ALL_DIRECTIVES = [DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0 + DIRECTIVES_DRAFT].flatten.uniq
7171
CONFIG_KEY = :csp
7272
end
7373

@@ -136,15 +136,18 @@ def initialize(config=nil, options={})
136136
@request_uri = options.delete(:request_uri)
137137
@http_additions = config.delete(:http_additions)
138138
@app_name = config.delete(:app_name)
139-
@enforce = !!config.delete(:enforce)
139+
@app_name = @app_name.call(@controller) if @app_name.respond_to?(:call)
140+
@enforce = config.delete(:enforce)
141+
@enforce = @enforce.call(@controller) if @enforce.respond_to?(:call)
142+
@enforce = !!@enforce
140143
@disable_img_src_data_uri = !!config.delete(:disable_img_src_data_uri)
141144
@tag_report_uri = !!config.delete(:tag_report_uri)
142145
@script_hashes = config.delete(:script_hashes) || []
143146

144147
# Config values can be string, array, or lamdba values
145148
@config = config.inject({}) do |hash, (key, value)|
146149
config_val = value.respond_to?(:call) ? value.call(@controller) : value
147-
if ContentSecurityPolicy::ALL_DIRECTIVES.include?(key.to_sym) # directives need to be normalized to arrays of strings
150+
if ([:enforce, :app_name] + ContentSecurityPolicy::ALL_DIRECTIVES).include?(key.to_sym) # directives need to be normalized to arrays of strings
148151
config_val = config_val.split if config_val.is_a? String
149152
if config_val.is_a?(Array)
150153
config_val = config_val.map do |val|
@@ -155,15 +158,31 @@ def initialize(config=nil, options={})
155158
raise ArgumentError.new("Unknown directive supplied: #{key}")
156159
end
157160

158-
159161
hash[key] = config_val
160162
hash
161163
end
162164

165+
# normalize and tag the report-uri
166+
if @config[:report_uri]
167+
@config[:report_uri] = @config[:report_uri].map do |report_uri|
168+
if report_uri.start_with?('//')
169+
report_uri = if @ssl_request
170+
"https:" + report_uri
171+
else
172+
"http:" + report_uri
173+
end
174+
end
175+
176+
if @tag_report_uri
177+
report_uri = "#{report_uri}?enforce=#{@enforce}"
178+
report_uri += "&app_name=#{@app_name}" if @app_name
179+
end
180+
report_uri
181+
end
182+
end
183+
163184
add_script_hashes if @script_hashes.any?
164-
puts @config
165185
strip_unsupported_directives
166-
puts @config
167186
end
168187

169188
##
@@ -198,12 +217,10 @@ def value
198217

199218
def to_json
200219
build_value
201-
out = @config.inject({}) do |hash, (key, value)|
220+
@config.inject({}) do |hash, (key, value)|
202221
hash[key.to_s.gsub(/(\w+)_(\w+)/, "\\1-\\2")] = value
203222
hash
204-
end
205-
puts out
206-
out.to_json
223+
end.to_json
207224
end
208225

209226
def self.from_json(*json_configs)
@@ -267,10 +284,12 @@ def generic_directives
267284
end
268285

269286
ALL_DIRECTIVES.each do |directive_name|
270-
header_value += build_directive(directive_name) if @config[directive_name]
287+
if @config[directive_name]
288+
header_value += build_directive(directive_name)
289+
end
271290
end
272291

273-
header_value
292+
header_value.strip
274293
end
275294

276295
def build_directive(key)

spec/lib/secure_headers/headers/content_security_policy_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def request_for user_agent, request_uri=nil, options={:ssl => false}
250250

251251
it "adds directive values for headers on http" do
252252
csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
253-
expect(csp.value).to eq("default-src https:; frame-src http:; img-src http: data:; script-src 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'unsafe-inline' https: about:; report-uri /csp_report;")
253+
expect(csp.value).to eq("default-src https:; frame-src http:; img-src https: data: http:; script-src 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'unsafe-inline' https: about:; report-uri /csp_report;")
254254
end
255255

256256
it "does not add the directive values if requesting https" do

0 commit comments

Comments
 (0)