Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

script hash rails integration PoC #67

Closed
wants to merge 15 commits into from
Next

detect partials

  • Loading branch information
oreoshake committed Sep 3, 2013
commit bcf3418efacd1394558c4cc05a5d222fa1de7e2e
@@ -21,6 +21,7 @@ def append_features(base)

module ClassMethods
attr_writer :secure_headers_options
attr_writer :script_hashes
def secure_headers_options
if @secure_headers_options
@secure_headers_options
@@ -31,8 +32,20 @@ def secure_headers_options
end
end

def script_hashes

This comment has been minimized.

Copy link
@oreoshake

oreoshake Sep 6, 2013

Author Collaborator

this is C/P'd from above. Generalize.

if @script_hashes
@script_hashes
elsif superclass.respond_to?(:script_hashes) # stop at application_controller

This comment has been minimized.

Copy link
@spikebrehm

spikebrehm Sep 3, 2014

This could be an issue if the superclass is itself a subclass of ApplicationController, yeah? i.e.:

MyController < AuthenticatedController < ApplicationController

Is it too hacky to recursively look up the superclass tree until it finds superclass.name == 'ApplicationController'?

This comment has been minimized.

Copy link
@oreoshake

oreoshake Sep 3, 2014

Author Collaborator

Sounds about right, I think that's only the case when you override settings from one controller to another. I guess this has just never come up :shrug:

superclass.script_hashes
else
raise "ERR"
end
end

def ensure_security_headers options = {}
self.script_hashes = YAML::load_file('config/script_hashes.yml')
self.secure_headers_options = options
before_filter :prep_script_hash
before_filter :set_hsts_header
before_filter :set_x_frame_options_header
before_filter :set_csp_header
@@ -52,6 +65,24 @@ def brwsr
@secure_headers_brwsr ||= Brwsr::Browser.new(:ua => request.env['HTTP_USER_AGENT'])
end

def prep_script_hash
@partial_events = []
@hashes = []
ActiveSupport::Notifications.subscribe("render_partial.action_view") do |event_name, start_at, end_at, id, payload|
# this happens after rendering... hack for now to gsub values
puts response.headers.inspect
@partial_events << payload[:identifier]
@hashes << self.class.script_hashes[payload[:identifier].gsub(Rails.root.to_s, "")].join(" ")
hashes = self.class.script_hashes[payload[:identifier].gsub(Rails.root.to_s, "")].join(",")

# get header name
header_name = ContentSecurityPolicy.new(nil, :request => request, :controller => self).name
puts response.headers[header_name]
response.headers[header_name] = response.headers[header_name].sub(/script-src/, "script-src sha-256:" + hashes)
puts response.headers[header_name]
end
end

# backwards compatibility jank, to be removed in 1.0. Old API required a request
# object when it didn't really need to.
# set_csp_header - uses the request accessor and SecureHeader::Configuration settings
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.