Skip to content

Commit 5ff1d1a

Browse files
arashndrzhade3
andauthored
Lowercase headers (#533)
Rack 3 `Response header keys can no longer include uppercase characters.` https://github.com/rack/rack/blob/main/UPGRADE-GUIDE.md#rack-3-upgrade-guide Rack Lint error out when using `secure_headers` because its adding headers with uppercase ``` Rack::Lint::LintError: uppercase character in header name: X-Frame-Options (Rack::Lint::LintError) ``` --------- Co-authored-by: Rahul Zhade <[email protected]>
1 parent b91d1d9 commit 5ff1d1a

19 files changed

+94
-78
lines changed

README.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ The gem will automatically apply several headers that are related to security.
1111
- X-Frame-Options (XFO) - Prevents your content from being framed and potentially clickjacked. [X-Frame-Options Specification](https://tools.ietf.org/html/rfc7034)
1212
- X-XSS-Protection - [Cross site scripting heuristic filter for IE/Chrome](https://msdn.microsoft.com/en-us/library/dd565647\(v=vs.85\).aspx)
1313
- X-Content-Type-Options - [Prevent content type sniffing](https://msdn.microsoft.com/library/gg622941\(v=vs.85\).aspx)
14-
- X-Download-Options - [Prevent file downloads opening](https://msdn.microsoft.com/library/jj542450(v=vs.85).aspx)
15-
- X-Permitted-Cross-Domain-Policies - [Restrict Adobe Flash Player's access to data](https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html)
16-
- Referrer-Policy - [Referrer Policy draft](https://w3c.github.io/webappsec-referrer-policy/)
17-
- Expect-CT - Only use certificates that are present in the certificate transparency logs. [Expect-CT draft specification](https://datatracker.ietf.org/doc/draft-stark-expect-ct/).
18-
- Clear-Site-Data - Clearing browser data for origin. [Clear-Site-Data specification](https://w3c.github.io/webappsec-clear-site-data/).
14+
- x-download-options - [Prevent file downloads opening](https://msdn.microsoft.com/library/jj542450(v=vs.85).aspx)
15+
- x-permitted-cross-domain-policies - [Restrict Adobe Flash Player's access to data](https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html)
16+
- referrer-policy - [Referrer Policy draft](https://w3c.github.io/webappsec-referrer-policy/)
17+
- expect-ct - Only use certificates that are present in the certificate transparency logs. [expect-ct draft specification](https://datatracker.ietf.org/doc/draft-stark-expect-ct/).
18+
- clear-site-data - Clearing browser data for origin. [clear-site-data specification](https://w3c.github.io/webappsec-clear-site-data/).
1919

2020
It can also mark all http cookies with the Secure, HttpOnly and SameSite attributes. This is on default but can be turned off by using `config.cookies = SecureHeaders::OPT_OUT`.
2121

@@ -99,13 +99,13 @@ end
9999
All headers except for PublicKeyPins and ClearSiteData have a default value. The default set of headers is:
100100

101101
```
102-
Content-Security-Policy: default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
103-
Strict-Transport-Security: max-age=631138519
104-
X-Content-Type-Options: nosniff
105-
X-Download-Options: noopen
106-
X-Frame-Options: sameorigin
107-
X-Permitted-Cross-Domain-Policies: none
108-
X-Xss-Protection: 0
102+
content-security-policy: default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
103+
strict-transport-security: max-age=631138519
104+
x-content-type-options: nosniff
105+
x-download-options: noopen
106+
x-frame-options: sameorigin
107+
x-permitted-cross-domain-policies: none
108+
x-xss-protection: 0
109109
```
110110

111111
## API configurations

docs/hashes.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ console.log(1)
5858
```
5959

6060
```
61-
Content-Security-Policy: ...
61+
content-security-policy: ...
6262
script-src 'sha256-yktKiAsZWmc8WpOyhnmhQoDf9G2dAZvuBBC+V0LGQhg=' ... ;
6363
style-src 'sha256-SLp6LO3rrKDJwsG9uJUxZapb4Wp2Zhj6Bu3l+d9rnAY=' 'sha256-HSGHqlRoKmHAGTAJ2Rq0piXX4CnEbOl1ArNd6ejp2TE=' ...;
6464
```

docs/per_action_configuration.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ body {
9191

9292
```
9393
94-
Content-Security-Policy: ...
94+
content-security-policy: ...
9595
script-src 'nonce-/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI=' ...;
9696
style-src 'nonce-/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI=' ...;
9797
```
@@ -118,13 +118,13 @@ You can clear the browser cache after the logout request by using the following.
118118

119119
``` ruby
120120
class ApplicationController < ActionController::Base
121-
# Configuration override to send the Clear-Site-Data header.
121+
# Configuration override to send the clear-site-data header.
122122
SecureHeaders::Configuration.override(:clear_browser_cache) do |config|
123123
config.clear_site_data = SecureHeaders::ClearSiteData::ALL_TYPES
124124
end
125125

126126

127-
# Clears the browser's cache for browsers supporting the Clear-Site-Data
127+
# Clears the browser's cache for browsers supporting the clear-site-data
128128
# header.
129129
#
130130
# Returns nothing.

docs/upgrading-to-4-0.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The default CSP has changed to be more universal without sacrificing too much se
1515

1616
Previously, the default CSP was:
1717

18-
`Content-Security-Policy: default-src 'self'`
18+
`content-security-policy: default-src 'self'`
1919

2020
The new default policy is:
2121

lib/secure_headers/configuration.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def csp=(new_csp)
256256
end
257257
end
258258

259-
# Configures the Content-Security-Policy-Report-Only header. `new_csp` cannot
259+
# Configures the content-security-policy-report-only header. `new_csp` cannot
260260
# contain `report_only: false` or an error will be raised.
261261
#
262262
# NOTE: if csp has not been configured/has the default value when

lib/secure_headers/headers/clear_site_data.rb

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
module SecureHeaders
33
class ClearSiteDataConfigError < StandardError; end
44
class ClearSiteData
5-
HEADER_NAME = "Clear-Site-Data".freeze
5+
HEADER_NAME = "clear-site-data".freeze
66

77
# Valid `types`
88
CACHE = "cache".freeze
@@ -12,7 +12,7 @@ class ClearSiteData
1212
ALL_TYPES = [CACHE, COOKIES, STORAGE, EXECUTION_CONTEXTS]
1313

1414
class << self
15-
# Public: make an Clear-Site-Data header name, value pair
15+
# Public: make an clear-site-data header name, value pair
1616
#
1717
# Returns nil if not configured, returns header name and value if configured.
1818
def make_header(config = nil, user_agent = nil)
@@ -39,8 +39,8 @@ def validate_config!(config)
3939
end
4040
end
4141

42-
# Public: Transform a Clear-Site-Data config (an Array of Strings) into a
43-
# String that can be used as the value for the Clear-Site-Data header.
42+
# Public: Transform a clear-site-data config (an Array of Strings) into a
43+
# String that can be used as the value for the clear-site-data header.
4444
#
4545
# types - An Array of String of types of data to clear.
4646
#

lib/secure_headers/headers/content_security_policy.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def initialize(config = nil)
2626
end
2727

2828
##
29-
# Returns the name to use for the header. Either "Content-Security-Policy" or
30-
# "Content-Security-Policy-Report-Only"
29+
# Returns the name to use for the header. Either "content-security-policy" or
30+
# "content-security-policy-report-only"
3131
def name
3232
@config.class.const_get(:HEADER_NAME)
3333
end

lib/secure_headers/headers/content_security_policy_config.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def write_attribute(attr, value)
7878

7979
class ContentSecurityPolicyConfigError < StandardError; end
8080
class ContentSecurityPolicyConfig
81-
HEADER_NAME = "Content-Security-Policy".freeze
81+
HEADER_NAME = "content-security-policy".freeze
8282

8383
ATTRS = Set.new(PolicyManagement::ALL_DIRECTIVES + PolicyManagement::META_CONFIGS + PolicyManagement::NONCES)
8484
def self.attrs
@@ -107,7 +107,7 @@ def make_report_only
107107
end
108108

109109
class ContentSecurityPolicyReportOnlyConfig < ContentSecurityPolicyConfig
110-
HEADER_NAME = "Content-Security-Policy-Report-Only".freeze
110+
HEADER_NAME = "content-security-policy-report-only".freeze
111111

112112
def report_only?
113113
true

lib/secure_headers/headers/expect_certificate_transparency.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ module SecureHeaders
33
class ExpectCertificateTransparencyConfigError < StandardError; end
44

55
class ExpectCertificateTransparency
6-
HEADER_NAME = "Expect-CT".freeze
6+
HEADER_NAME = "expect-ct".freeze
77
INVALID_CONFIGURATION_ERROR = "config must be a hash.".freeze
88
INVALID_ENFORCE_VALUE_ERROR = "enforce must be a boolean".freeze
99
REQUIRED_MAX_AGE_ERROR = "max-age is a required directive.".freeze
1010
INVALID_MAX_AGE_ERROR = "max-age must be a number.".freeze
1111

1212
class << self
13-
# Public: Generate a Expect-CT header.
13+
# Public: Generate a expect-ct header.
1414
#
1515
# Returns nil if not configured, returns header name and value if
1616
# configured.

lib/secure_headers/headers/policy_management.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ def self.included(base)
9898

9999
# Experimental directives - these vary greatly in support
100100
# See MDN for details.
101-
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
101+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/content-security-policy/trusted-types
102102
TRUSTED_TYPES = :trusted_types
103-
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-trusted-types-for
103+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/content-security-policy/require-trusted-types-for
104104
REQUIRE_TRUSTED_TYPES_FOR = :require_trusted_types_for
105105

106106
DIRECTIVES_EXPERIMENTAL = [

lib/secure_headers/headers/referrer_policy.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
module SecureHeaders
33
class ReferrerPolicyConfigError < StandardError; end
44
class ReferrerPolicy
5-
HEADER_NAME = "Referrer-Policy".freeze
5+
HEADER_NAME = "referrer-policy".freeze
66
DEFAULT_VALUE = "origin-when-cross-origin"
77
VALID_POLICIES = %w(
88
no-referrer

lib/secure_headers/headers/strict_transport_security.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module SecureHeaders
33
class STSConfigError < StandardError; end
44

55
class StrictTransportSecurity
6-
HEADER_NAME = "Strict-Transport-Security".freeze
6+
HEADER_NAME = "strict-transport-security".freeze
77
HSTS_MAX_AGE = "631138519"
88
DEFAULT_VALUE = "max-age=" + HSTS_MAX_AGE
99
VALID_STS_HEADER = /\Amax-age=\d+(; includeSubdomains)?(; preload)?\z/i

lib/secure_headers/headers/x_content_type_options.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module SecureHeaders
33
class XContentTypeOptionsConfigError < StandardError; end
44

55
class XContentTypeOptions
6-
HEADER_NAME = "X-Content-Type-Options".freeze
6+
HEADER_NAME = "x-content-type-options".freeze
77
DEFAULT_VALUE = "nosniff"
88

99
class << self

lib/secure_headers/headers/x_download_options.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
module SecureHeaders
33
class XDOConfigError < StandardError; end
44
class XDownloadOptions
5-
HEADER_NAME = "X-Download-Options".freeze
5+
HEADER_NAME = "x-download-options".freeze
66
DEFAULT_VALUE = "noopen"
77

88
class << self
9-
# Public: generate an X-Download-Options header.
9+
# Public: generate an x-download-options header.
1010
#
1111
# Returns a default header if no configuration is provided, or a
1212
# header name and value based on the config.

lib/secure_headers/headers/x_frame_options.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
module SecureHeaders
33
class XFOConfigError < StandardError; end
44
class XFrameOptions
5-
HEADER_NAME = "X-Frame-Options".freeze
5+
HEADER_NAME = "x-frame-options".freeze
66
SAMEORIGIN = "sameorigin"
77
DENY = "deny"
88
ALLOW_FROM = "allow-from"

lib/secure_headers/headers/x_permitted_cross_domain_policies.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
module SecureHeaders
33
class XPCDPConfigError < StandardError; end
44
class XPermittedCrossDomainPolicies
5-
HEADER_NAME = "X-Permitted-Cross-Domain-Policies".freeze
5+
HEADER_NAME = "x-permitted-cross-domain-policies".freeze
66
DEFAULT_VALUE = "none"
77
VALID_POLICIES = %w(all none master-only by-content-type by-ftp-filename)
88

99
class << self
10-
# Public: generate an X-Permitted-Cross-Domain-Policies header.
10+
# Public: generate an x-permitted-cross-domain-policies header.
1111
#
1212
# Returns a default header if no configuration is provided, or a
1313
# header name and value based on the config.

lib/secure_headers/headers/x_xss_protection.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
module SecureHeaders
33
class XXssProtectionConfigError < StandardError; end
44
class XXssProtection
5-
HEADER_NAME = "X-XSS-Protection".freeze
5+
HEADER_NAME = "x-xss-protection".freeze
66
DEFAULT_VALUE = "0".freeze
77
VALID_X_XSS_HEADER = /\A[01](; mode=block)?(; report=.*)?\z/
88

lib/secure_headers/railtie.rb

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
module SecureHeaders
55
class Railtie < Rails::Railtie
66
isolate_namespace SecureHeaders if defined? isolate_namespace # rails 3.0
7-
conflicting_headers = ["X-Frame-Options", "X-XSS-Protection",
8-
"X-Permitted-Cross-Domain-Policies", "X-Download-Options",
9-
"X-Content-Type-Options", "Strict-Transport-Security",
10-
"Content-Security-Policy", "Content-Security-Policy-Report-Only",
11-
"Public-Key-Pins", "Public-Key-Pins-Report-Only", "Referrer-Policy"]
7+
conflicting_headers = ["x-frame-options", "x-xss-protection",
8+
"x-permitted-cross-domain-policies", "x-download-options",
9+
"x-content-type-options", "strict-transport-security",
10+
"content-security-policy", "content-security-policy-report-only",
11+
"public-key-pins", "public-key-pins-report-only", "referrer-policy"]
1212

1313
initializer "secure_headers.middleware" do
1414
Rails.application.config.middleware.insert_before 0, SecureHeaders::Middleware

0 commit comments

Comments
 (0)