Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Introduce default_headers. closes #6311 #6515 #7302

Merged
merged 2 commits into from

10 participants

Egor Homakov Rafael Mendonça França Steve Klabnik Eric Thomas Jim Jones Aaron Patterson Santiago Pastorino Piotr Sarnacki Francesco Rodríguez José Valim
Egor Homakov

4.0 feature, everybody agreed to merge it.
Default headers are really useful for various security options and mitigations.

discuss: should we add "Sniff content type" header

Rafael Mendonça França
Owner

Related with #6311 and #6515 (commenting since github doesn't link issues at the title)

Rafael Mendonça França
Owner

@homakov Thank you. Could you add some tests?

Egor Homakov

@rafaelfranca thanks, here they are

Steve Klabnik
Collaborator

So, it's now considered not best practice to use the X-* pattern when minting new HTTP headers: http://tools.ietf.org/html/rfc6648

Egor Homakov

@steveklabnik yea have seen it and lold :) this 'over standardizing' looks funny.

You sure all browsers support Frame-Options along X-Frame-Options? if yes I will change it.

Steve Klabnik
Collaborator

Is 'X-Frame-Options' an existing header, or a new one? I'm not super familiar with security issues.

If it's old, then obviously, we use it verbatim. If 'browser support' means do browsers can handle a new header without the X- prefix, then yes, as far as I know, they all do.

Egor Homakov

@steveklabnik yes, both X- headers are extremely old so we hardly can remove 'X-' prefix.
X-XSS-Protection controls built in IE and Chrome anti xss auditor.
X-Frame-Options detects should website be visible in iframes or not. 99% of websites don't need to be shown in iframes.

Steve Klabnik
Collaborator

Ah! Then continue. I thought they were something new you were making. No worries. TIL.

Eric Thomas
et commented

+1 These are great defaults that everyone will probably want turned on.

Jim Jones

+1 We're currently manually adding these defaults for the current client I am working with. It's coupled with complimentary frame busting code, but that's probably a separate story.

Egor Homakov

@aantix regards framebusting - make sure you use "modern framekiller" when page is hidden by default and then shown if everything is ok. other framekillers don't work.

c'mon, merge or die trying

Aaron Patterson
Owner

Seems good. Thanks @homakov!

Aaron Patterson tenderlove merged commit 6794e92 into from
Aaron Patterson tenderlove closed this
Piotr Sarnacki
Collaborator

Can we have better commit messages next time? As showed here: http://guides.rubyonrails.org/contributing_to_ruby_on_rails.html#commit-your-changes

Egor Homakov

@drogus my bad, forgot that commit message is what i write in -m and not in title of PR.

@tenderlove Spasibo :)

José Valim josevalim commented on the diff
.../generators/rails/app/templates/config/application.rb
@@ -41,6 +41,11 @@ class Application < Rails::Application
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
+ config.action_dispatch.default_headers = {
José Valim Owner

I don't think these configs should be in config/application.rb, but rather in the action dispatch railtie.

Egor Homakov
homakov added a note

IMO this is a perfect place. Developer sees clearly where and how default headers are defined. Also, how is he supposed to remove them if he doesn't need Frame-Options? We cannot "hardcode" these values.

José Valim Owner

config.action_dispatch.default_headers.clear would clear them. Rails has many defaults, we don't list them all on config/application.rb for a reason. Documentation solves the problem of knowing what is on by default and how to clear it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Santiago Pastorino
Owner

Can we have a CHANGELOG entry for this?

Egor Homakov

@spastorino do we still add changelog changes in PRs? :) You can add it if dont mind

Santiago Pastorino
Owner

@homakov we shouldn't be merging PRs without CHANGELOG entries or we should merge and add CHANGELOG entries later but I prefer asking contributors for that. I have merged things without CHANGELOG entries but I don't consider that a good practice anyway. I'm guilty too ;).

Santiago Pastorino
Owner

pushed 0b11dbe

Egor Homakov

@spastorino thannnkss :)

@josevalim i see your point but cannot do so. Explicit definition here looks like common sense to me.

for example we have config.filter_parameters += [:password] but we also could have it built in and ask developers to write config.filter_parameters -= [:password] if they don't want to filter passwords. It is a bit 'monkey patching'. Please, let's leave it as is, I think it's a better option.

Piotr Sarnacki
Collaborator

To confirm how should we deal with CHANGELOG entries, I've pushed a commit describing it to contributing guide: adf3ea3 I'm serial offender, too, and I probably haven't added CHANGELOG entries to a lot of things myself, but just as with commit messages, I would like to hold any PR that needs fixing this - it may make merging harder and this green button is really tempting, but as we have more commiters and more commits in general, it will be much easier to deal with it this way.

Santiago Pastorino
Owner

Is there a reason for not adding also "X-Content-Type-Options" => "nosniff" ?.
@homakov what about the other headers you proposed in the first place?

Egor Homakov

@spastorino we should add it too. Yet another header to make IE less mad. Go ahead, it can be default :)

Also, if you will write a tutorial, you can find default_headers feature useful for Access-Control-Allow-Origin and X-Content-Security-Policy which are popular headers(http://recxltd.blogspot.com/2012/03/seven-web-server-http-headers-that.html)

@josevalim now I can see values hardcoded inside of ActionDispatcher. It's OK, but i'm afraid that people will get broken framing by updating rails to 4 ver. They will be surprised :(

Jim Jones

@homakov @spastorino @josevalim Just submitted a pull request to add the X-Content-Type-Options header.

#7390

Jim Jones

I don't think any of the other headers, (Cache-Control, X-Content-Security-Policy, Strict-Transport-Security, Access-Control-Allow-Origin) should have defaults.

Egor Homakov

@spastorino they should be per-app configured.. up to developers.

Jim Jones

My comment above agrees with @homakov

Santiago Pastorino
Owner

Yeah, so could be nice to document about them and that as a developer you could change default_headers if you want to.

Egor Homakov

@spastorino I will manage it. As those are mostly security-related headers I want to update this document http://guides.rubyonrails.org/security.html

Santiago Pastorino
Owner

@homakov sure, go ahead

Jim Jones

@homakov Let me know if you want any help.

Egor Homakov

@spastorino @aantix guys pls have a look at https://github.com/lifo/docrails/pull/108/files
I described the most common headers. if you wish to add some more headers - welcome. (and, yeah, welcome to fix my grammar :) )

Santiago Pastorino
Owner

@homakov :+1: you're free to push that to docrails

Egor Homakov

@spastorino yes i pushed :) Just want to see it "here":http://guides.rubyonrails.org/security.html

Steve Klabnik
Collaborator

Well it won't be out on that page until a release. And since this went into master, that'd be the release of Rails 4.

Francesco Rodríguez

Also, you will see it "here":http://edgeguides.rubyonrails.org/security.html when docrails changes get merged in master.

Egor Homakov

@steveklabnik @frodsan got it, no rush.
I think mass assignment section also will need to get updated when we get strong_parameters merged.

Jim Jones

@spastorino @homakov I added some clarifications to the security documentation surrounding what the default values are and how to clear them.

rails/docrails#109

Santiago Pastorino
Owner

@aantix as @fxn told you, please push the changes directly to docrails, everyone has commit bit there :)

Jim Jones

@spastorino Merged in my changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 9, 2012
  1. Egor Homakov
  2. Egor Homakov

    some tests

    homakov authored
This page is out of date. Refresh to see the latest.
5 actionpack/lib/action_dispatch/http/response.rb
View
@@ -58,6 +58,7 @@ class Response
LOCATION = "Location".freeze
cattr_accessor(:default_charset) { "utf-8" }
+ cattr_accessor(:default_headers)
include Rack::Response::Helpers
include ActionDispatch::Http::Cache::Response
@@ -96,6 +97,10 @@ def closed?
def initialize(status = 200, header = {}, body = [])
super()
+ if self.class.default_headers.respond_to?(:merge)
+ header = self.class.default_headers.merge(header)
+ end
+
self.body, self.header, self.status = body, header, status
@sending_file = false
1  actionpack/lib/action_dispatch/railtie.rb
View
@@ -23,6 +23,7 @@ class Railtie < Rails::Railtie
ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
ActionDispatch::Response.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
+ ActionDispatch::Response.default_headers = app.config.action_dispatch.default_headers
ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses)
ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates)
27 actionpack/test/dispatch/response_test.rb
View
@@ -176,6 +176,33 @@ def test_response_body_encoding
ActionDispatch::Response.default_charset = original
end
end
+
+ test "read x_frame_options and x_xss_protection" do
+ ActionDispatch::Response.default_headers = {
+ 'X-Frame-Options' => 'DENY',
+ 'X-XSS-Protection' => '1;'
+ }
+ resp = ActionDispatch::Response.new.tap { |response|
+ response.body = 'Hello'
+ }
+ resp.to_a
+
+ assert_equal('DENY', resp.headers['X-Frame-Options'])
+ assert_equal('1;', resp.headers['X-XSS-Protection'])
+ end
+
+ test "read custom default_header" do
+ ActionDispatch::Response.default_headers = {
+ 'X-XX-XXXX' => 'Here is my phone number'
+ }
+ resp = ActionDispatch::Response.new.tap { |response|
+ response.body = 'Hello'
+ }
+ resp.to_a
+
+ assert_equal('Here is my phone number', resp.headers['X-XX-XXXX'])
+ end
+
end
class ResponseIntegrationTest < ActionDispatch::IntegrationTest
5 railties/lib/rails/generators/rails/app/templates/config/application.rb
View
@@ -41,6 +41,11 @@ class Application < Rails::Application
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
+ config.action_dispatch.default_headers = {
José Valim Owner

I don't think these configs should be in config/application.rb, but rather in the action dispatch railtie.

Egor Homakov
homakov added a note

IMO this is a perfect place. Developer sees clearly where and how default headers are defined. Also, how is he supposed to remove them if he doesn't need Frame-Options? We cannot "hardcode" these values.

José Valim Owner

config.action_dispatch.default_headers.clear would clear them. Rails has many defaults, we don't list them all on config/application.rb for a reason. Documentation solves the problem of knowing what is on by default and how to clear it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ 'X-Frame-Options' => 'SAMEORIGIN',
+ 'X-XSS-Protection' => '1; mode=block'
+ }
+
# Use SQL instead of Active Record's schema dumper when creating the database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types.
Something went wrong with that request. Please try again.