secure_headers 3.9.0 → 4.0.0.alpha01
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of secure_headers might be problematic. Click here for more details.
- checksums.yaml +5 -5
 - data/.rspec +1 -0
 - data/.rubocop.yml +3 -0
 - data/.ruby-version +1 -1
 - data/.travis.yml +8 -6
 - data/CHANGELOG.md +2 -34
 - data/CONTRIBUTING.md +1 -1
 - data/Gemfile +7 -4
 - data/Guardfile +1 -0
 - data/README.md +4 -25
 - data/Rakefile +22 -18
 - data/docs/cookies.md +18 -5
 - data/lib/secure_headers.rb +1 -2
 - data/lib/secure_headers/configuration.rb +6 -16
 - data/lib/secure_headers/hash_helper.rb +2 -1
 - data/lib/secure_headers/headers/clear_site_data.rb +2 -1
 - data/lib/secure_headers/headers/content_security_policy.rb +14 -60
 - data/lib/secure_headers/headers/content_security_policy_config.rb +1 -1
 - data/lib/secure_headers/headers/cookie.rb +22 -10
 - data/lib/secure_headers/headers/policy_management.rb +57 -98
 - data/lib/secure_headers/headers/public_key_pins.rb +4 -3
 - data/lib/secure_headers/headers/referrer_policy.rb +1 -0
 - data/lib/secure_headers/headers/strict_transport_security.rb +2 -1
 - data/lib/secure_headers/headers/x_content_type_options.rb +1 -0
 - data/lib/secure_headers/headers/x_download_options.rb +2 -1
 - data/lib/secure_headers/headers/x_frame_options.rb +1 -0
 - data/lib/secure_headers/headers/x_permitted_cross_domain_policies.rb +2 -1
 - data/lib/secure_headers/headers/x_xss_protection.rb +2 -1
 - data/lib/secure_headers/middleware.rb +10 -9
 - data/lib/secure_headers/railtie.rb +7 -6
 - data/lib/secure_headers/utils/cookies_config.rb +17 -18
 - data/lib/secure_headers/view_helper.rb +2 -1
 - data/lib/tasks/tasks.rake +2 -1
 - data/secure_headers.gemspec +13 -3
 - data/spec/lib/secure_headers/configuration_spec.rb +9 -8
 - data/spec/lib/secure_headers/headers/clear_site_data_spec.rb +2 -1
 - data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +17 -53
 - data/spec/lib/secure_headers/headers/cookie_spec.rb +58 -37
 - data/spec/lib/secure_headers/headers/policy_management_spec.rb +20 -41
 - data/spec/lib/secure_headers/headers/public_key_pins_spec.rb +7 -6
 - data/spec/lib/secure_headers/headers/referrer_policy_spec.rb +4 -3
 - data/spec/lib/secure_headers/headers/strict_transport_security_spec.rb +5 -4
 - data/spec/lib/secure_headers/headers/x_content_type_options_spec.rb +2 -1
 - data/spec/lib/secure_headers/headers/x_download_options_spec.rb +3 -2
 - data/spec/lib/secure_headers/headers/x_frame_options_spec.rb +2 -1
 - data/spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb +4 -3
 - data/spec/lib/secure_headers/headers/x_xss_protection_spec.rb +4 -3
 - data/spec/lib/secure_headers/middleware_spec.rb +18 -21
 - data/spec/lib/secure_headers/view_helpers_spec.rb +5 -4
 - data/spec/lib/secure_headers_spec.rb +92 -120
 - data/spec/spec_helper.rb +9 -23
 - data/upgrading-to-4-0.md +49 -0
 - metadata +16 -11
 - data/lib/secure_headers/headers/expect_certificate_transparency.rb +0 -70
 - data/spec/lib/secure_headers/headers/expect_certificate_transparency_spec.rb +0 -42
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 1cfa800eacf250583e379d13a9149d585bc2f48d
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 3de8c81b1308ec9d1d53f822cff8eeb7e20b5af0
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 4c25ae5372ac00f74b0cae3b7de0a767a15b45f275bed64994c2cd7d078a2f0b52bdce562d14280984ad494fd008445d5d5448a3ac94694cd1f9778da3deeacc
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 6fab2c382ed56f9a63dd118a34b617fb82b4ee4e9ef55f37d78e134ec9068c9ee1022ba0a94991d0b7b82ea756d78132d3c0dfc909e66d4068acde4f6d2673ff
         
     | 
    
        data/.rspec
    CHANGED
    
    
    
        data/.rubocop.yml
    ADDED
    
    
    
        data/.ruby-version
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            2. 
     | 
| 
      
 1 
     | 
    
         
            +
            2.4.1
         
     | 
    
        data/.travis.yml
    CHANGED
    
    | 
         @@ -2,15 +2,17 @@ language: ruby 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            rvm:
         
     | 
| 
       4 
4 
     | 
    
         
             
              - ruby-head
         
     | 
| 
       5 
     | 
    
         
            -
              - 2.4. 
     | 
| 
       6 
     | 
    
         
            -
              - 2.3. 
     | 
| 
      
 5 
     | 
    
         
            +
              - 2.4.1
         
     | 
| 
      
 6 
     | 
    
         
            +
              - 2.3.4
         
     | 
| 
       7 
7 
     | 
    
         
             
              - 2.2
         
     | 
| 
       8 
     | 
    
         
            -
              - 2.1
         
     | 
| 
       9 
     | 
    
         
            -
              - 2.0.0
         
     | 
| 
       10 
     | 
    
         
            -
              - 1.9.3
         
     | 
| 
       11 
     | 
    
         
            -
              - jruby-19mode
         
     | 
| 
       12 
8 
     | 
    
         
             
              - jruby-head
         
     | 
| 
       13 
9 
     | 
    
         | 
| 
      
 10 
     | 
    
         
            +
            env:
         
     | 
| 
      
 11 
     | 
    
         
            +
              - SUITE=rspec spec
         
     | 
| 
      
 12 
     | 
    
         
            +
              - SUITE=rubocop
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            script: bundle exec $SUITE
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
       14 
16 
     | 
    
         
             
            matrix:
         
     | 
| 
       15 
17 
     | 
    
         
             
              allow_failures:
         
     | 
| 
       16 
18 
     | 
    
         
             
                - rvm: jruby-head
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,38 +1,6 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            ##  
     | 
| 
      
 1 
     | 
    
         
            +
            ## 4.x
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            ## 3.8.0
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            Fixes semicolon injection issue reported by @mvgijssel see https://github.com/twitter/secure_headers/issues/418
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            ## 3.7.4
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            Backport SameSite=None functionality into 3.x line
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            ## 3.7.3
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            - Updates `Expect-CT` header to use a comma separator between directives, as specified in the most current spec.
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
            ## 3.7.2
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            - Adds support for `worker-src` CSP directive to 3.x line (https://github.com/twitter/secureheaders/pull/364)
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
            ## 3.7.1
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            Fix support for the sandbox attribute of CSP. `true` and `[]` represent the maximally restricted policy (`sandbox;`) and validate other values.
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
            ## 3.7.0
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
            Adds support for the `Expect-CT` header (@jacobbednarz: https://github.com/twitter/secureheaders/pull/322)
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            ## 3.6.7
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
            Actually set manifest-src when configured. https://github.com/twitter/secureheaders/pull/339 Thanks @carlosantoniodasilva!
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
            ## 3.6.6
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            wat?
         
     | 
| 
      
 3 
     | 
    
         
            +
            - See the [upgrading to 4.0](upgrading-to-4.0.md) guide. Lots of breaking changes.
         
     | 
| 
       36 
4 
     | 
    
         | 
| 
       37 
5 
     | 
    
         
             
            ## 3.6.5
         
     | 
| 
       38 
6 
     | 
    
         | 
    
        data/CONTRIBUTING.md
    CHANGED
    
    | 
         @@ -30,7 +30,7 @@ Here are a few things you can do that will increase the likelihood of your pull 
     | 
|
| 
       30 
30 
     | 
    
         
             
            0. Ensure CI is green
         
     | 
| 
       31 
31 
     | 
    
         
             
            0. Pull the latest code
         
     | 
| 
       32 
32 
     | 
    
         
             
            0. Increment the version
         
     | 
| 
       33 
     | 
    
         
            -
            0. Run `gem build  
     | 
| 
      
 33 
     | 
    
         
            +
            0. Run `gem build secure_headers.gemspec`
         
     | 
| 
       34 
34 
     | 
    
         
             
            0. Bump the Gemfile and Gemfile.lock versions for an app which relies on this gem
         
     | 
| 
       35 
35 
     | 
    
         
             
            0. Test behavior locally, branch deploy, whatever needs to happen
         
     | 
| 
       36 
36 
     | 
    
         
             
            0. Run `bundle exec rake release`
         
     | 
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -1,19 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            source "https://rubygems.org"
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            gemspec
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            group :test do
         
     | 
| 
       6 
     | 
    
         
            -
              gem " 
     | 
| 
       7 
     | 
    
         
            -
              gem "pry-nav"
         
     | 
| 
      
 7 
     | 
    
         
            +
              gem "coveralls"
         
     | 
| 
       8 
8 
     | 
    
         
             
              gem "json", "~> 1"
         
     | 
| 
      
 9 
     | 
    
         
            +
              gem "pry-nav"
         
     | 
| 
       9 
10 
     | 
    
         
             
              gem "rack", "~> 1"
         
     | 
| 
       10 
11 
     | 
    
         
             
              gem "rspec"
         
     | 
| 
       11 
     | 
    
         
            -
              gem " 
     | 
| 
      
 12 
     | 
    
         
            +
              gem "rubocop", "~> 0.47.0"
         
     | 
| 
      
 13 
     | 
    
         
            +
              gem "rubocop-github"
         
     | 
| 
       12 
14 
     | 
    
         
             
              gem "term-ansicolor", "< 1.4"
         
     | 
| 
      
 15 
     | 
    
         
            +
              gem "tins", "~> 1.6.0" # 1.7 requires ruby 2.0
         
     | 
| 
       13 
16 
     | 
    
         
             
            end
         
     | 
| 
       14 
17 
     | 
    
         | 
| 
       15 
18 
     | 
    
         
             
            group :guard do
         
     | 
| 
       16 
     | 
    
         
            -
              gem "guard-rspec", platforms: [:ruby_19, :ruby_20, :ruby_21, :ruby_22]
         
     | 
| 
       17 
19 
     | 
    
         
             
              gem "growl"
         
     | 
| 
      
 20 
     | 
    
         
            +
              gem "guard-rspec", platforms: [:ruby_19, :ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24]
         
     | 
| 
       18 
21 
     | 
    
         
             
              gem "rb-fsevent"
         
     | 
| 
       19 
22 
     | 
    
         
             
            end
         
     | 
    
        data/Guardfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,9 +1,10 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Secure Headers [](http://travis-ci.org/twitter/secureheaders) [](https://codeclimate.com/github/twitter/secureheaders) [](https://coveralls.io/r/twitter/secureheaders)
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            **master represents the unreleased 4.x line**. See the [upgrading to 4.x doc](upgrading-to-4-0.md) for instructions on how to upgrade. Bug fixes should go in the 3.x branch for now.
         
     | 
| 
       3 
4 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            **The 3.x branch  
     | 
| 
      
 5 
     | 
    
         
            +
            **The [3.x](https://github.com/twitter/secureheaders/tree/2.x) branch is moving into maintenance mode**. See the [upgrading to 3.x doc](upgrading-to-3-0.md) for instructions on how to upgrade including the differences and benefits of using the 3.x branch.
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            **The [2.x branch](https://github.com/twitter/secureheaders/tree/2.x) will be maintained**. The documentation below only applies to the 3.x branch. See the 2.x [README](https://github.com/twitter/secureheaders/blob/2.x/README.md) for the old way of doing things.
         
     | 
| 
      
 7 
     | 
    
         
            +
            **The [2.x branch](https://github.com/twitter/secureheaders/tree/2.x) will be not be maintained once 4.x is released**. The documentation below only applies to the 3.x branch. See the 2.x [README](https://github.com/twitter/secureheaders/blob/2.x/README.md) for the old way of doing things.
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
            The gem will automatically apply several headers that are related to security.  This includes:
         
     | 
| 
       9 
10 
     | 
    
         
             
            - Content Security Policy (CSP) - Helps detect/prevent XSS, mixed-content, and other classes of attack.  [CSP 2 Specification](http://www.w3.org/TR/CSP2/)
         
     | 
| 
         @@ -18,7 +19,6 @@ The gem will automatically apply several headers that are related to security. 
     | 
|
| 
       18 
19 
     | 
    
         
             
            - 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)
         
     | 
| 
       19 
20 
     | 
    
         
             
            - Referrer-Policy - [Referrer Policy draft](https://w3c.github.io/webappsec-referrer-policy/)
         
     | 
| 
       20 
21 
     | 
    
         
             
            - Public Key Pinning - Pin certificate fingerprints in the browser to prevent man-in-the-middle attacks due to compromised Certificate Authorities. [Public Key Pinning Specification](https://tools.ietf.org/html/rfc7469)
         
     | 
| 
       21 
     | 
    
         
            -
            - 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/).
         
     | 
| 
       22 
22 
     | 
    
         
             
            - Clear-Site-Data - Clearing browser data for origin. [Clear-Site-Data specification](https://w3c.github.io/webappsec-clear-site-data/).
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
            It can also mark all http cookies with the Secure, HttpOnly and SameSite attributes (when configured to do so).
         
     | 
| 
         @@ -77,14 +77,8 @@ SecureHeaders::Configuration.default do |config| 
     | 
|
| 
       77 
77 
     | 
    
         
             
                "storage",
         
     | 
| 
       78 
78 
     | 
    
         
             
                "executionContexts"
         
     | 
| 
       79 
79 
     | 
    
         
             
              ]
         
     | 
| 
       80 
     | 
    
         
            -
              config.expect_certificate_transparency = {
         
     | 
| 
       81 
     | 
    
         
            -
                enforce: false,
         
     | 
| 
       82 
     | 
    
         
            -
                max_age: 1.day.to_i,
         
     | 
| 
       83 
     | 
    
         
            -
                report_uri: "https://report-uri.io/example-ct"
         
     | 
| 
       84 
     | 
    
         
            -
              }
         
     | 
| 
       85 
80 
     | 
    
         
             
              config.csp = {
         
     | 
| 
       86 
     | 
    
         
            -
                # "meta" values. these will  
     | 
| 
       87 
     | 
    
         
            -
                # report_only: true,      # default: false [DEPRECATED from 3.5.0: instead, configure csp_report_only]
         
     | 
| 
      
 81 
     | 
    
         
            +
                # "meta" values. these will shape the header, but the values are not included in the header.
         
     | 
| 
       88 
82 
     | 
    
         
             
                preserve_schemes: true, # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
         
     | 
| 
       89 
83 
     | 
    
         | 
| 
       90 
84 
     | 
    
         
             
                # directive values: these values will directly translate into source directives
         
     | 
| 
         @@ -103,7 +97,6 @@ SecureHeaders::Configuration.default do |config| 
     | 
|
| 
       103 
97 
     | 
    
         
             
                plugin_types: %w(application/x-shockwave-flash),
         
     | 
| 
       104 
98 
     | 
    
         
             
                script_src: %w('self'),
         
     | 
| 
       105 
99 
     | 
    
         
             
                style_src: %w('unsafe-inline'),
         
     | 
| 
       106 
     | 
    
         
            -
                worker_src: %w('self'),
         
     | 
| 
       107 
100 
     | 
    
         
             
                upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
         
     | 
| 
       108 
101 
     | 
    
         
             
                report_uri: %w(https://report-uri.io/example-csp)
         
     | 
| 
       109 
102 
     | 
    
         
             
              }
         
     | 
| 
         @@ -139,20 +132,6 @@ X-Permitted-Cross-Domain-Policies: none 
     | 
|
| 
       139 
132 
     | 
    
         
             
            X-Xss-Protection: 1; mode=block
         
     | 
| 
       140 
133 
     | 
    
         
             
            ```
         
     | 
| 
       141 
134 
     | 
    
         | 
| 
       142 
     | 
    
         
            -
            ### Default CSP
         
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
            By default, the above CSP will be applied to all requests. If you **only** want to set a Report-Only header, opt-out of the default enforced header for clarity. The configuration will assume that if you only supply `csp_report_only` that you intended to opt-out of `csp` but that's for the sake of backwards compatibility and it will be removed in the future.
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       147 
     | 
    
         
            -
            Configuration.default do |config|
         
     | 
| 
       148 
     | 
    
         
            -
              config.csp = SecureHeaders::OPT_OUT # If this line is omitted, we will assume you meant to opt out.
         
     | 
| 
       149 
     | 
    
         
            -
              config.csp_report_only = {
         
     | 
| 
       150 
     | 
    
         
            -
                default_src: %w('self')
         
     | 
| 
       151 
     | 
    
         
            -
              }
         
     | 
| 
       152 
     | 
    
         
            -
            end
         
     | 
| 
       153 
     | 
    
         
            -
            ```
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
135 
     | 
    
         
             
            ## Similar libraries
         
     | 
| 
       157 
136 
     | 
    
         | 
| 
       158 
137 
     | 
    
         
             
            * Rack [rack-secure_headers](https://github.com/frodsan/rack-secure_headers)
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -1,28 +1,32 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/usr/bin/env rake
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
       4 
     | 
    
         
            -
            require  
     | 
| 
       5 
     | 
    
         
            -
            require  
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "bundler/gem_tasks"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "rspec/core/rake_task"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "net/http"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "net/https"
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            RSpec::Core::RakeTask.new do |t|
         
     | 
| 
       9 
     | 
    
         
            -
              t.verbose = false
         
     | 
| 
       10 
     | 
    
         
            -
              t.rspec_opts = "--format progress"
         
     | 
| 
       11 
     | 
    
         
            -
            end
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            task default: :spec
         
     | 
| 
      
 8 
     | 
    
         
            +
            RSpec::Core::RakeTask.new
         
     | 
| 
       14 
9 
     | 
    
         | 
| 
       15 
10 
     | 
    
         
             
            begin
         
     | 
| 
       16 
     | 
    
         
            -
              require  
     | 
| 
      
 11 
     | 
    
         
            +
              require "rdoc/task"
         
     | 
| 
       17 
12 
     | 
    
         
             
            rescue LoadError
         
     | 
| 
       18 
     | 
    
         
            -
              require  
     | 
| 
       19 
     | 
    
         
            -
              require  
     | 
| 
      
 13 
     | 
    
         
            +
              require "rdoc/rdoc"
         
     | 
| 
      
 14 
     | 
    
         
            +
              require "rake/rdoctask"
         
     | 
| 
       20 
15 
     | 
    
         
             
              RDoc::Task = Rake::RDocTask
         
     | 
| 
       21 
16 
     | 
    
         
             
            end
         
     | 
| 
       22 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
            begin
         
     | 
| 
      
 19 
     | 
    
         
            +
              require "rubocop/rake_task"
         
     | 
| 
      
 20 
     | 
    
         
            +
              RuboCop::RakeTask.new
         
     | 
| 
      
 21 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 22 
     | 
    
         
            +
              task(:rubocop) { $stderr.puts "RuboCop is disabled" }
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       23 
25 
     | 
    
         
             
            RDoc::Task.new(:rdoc) do |rdoc|
         
     | 
| 
       24 
     | 
    
         
            -
              rdoc.rdoc_dir =  
     | 
| 
       25 
     | 
    
         
            -
              rdoc.title    =  
     | 
| 
       26 
     | 
    
         
            -
              rdoc.options <<  
     | 
| 
       27 
     | 
    
         
            -
              rdoc.rdoc_files.include( 
     | 
| 
      
 26 
     | 
    
         
            +
              rdoc.rdoc_dir = "rdoc"
         
     | 
| 
      
 27 
     | 
    
         
            +
              rdoc.title    = "SecureHeaders"
         
     | 
| 
      
 28 
     | 
    
         
            +
              rdoc.options << "--line-numbers"
         
     | 
| 
      
 29 
     | 
    
         
            +
              rdoc.rdoc_files.include("lib/**/*.rb")
         
     | 
| 
       28 
30 
     | 
    
         
             
            end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            task default: [:spec, :rubocop]
         
     | 
    
        data/docs/cookies.md
    CHANGED
    
    | 
         @@ -4,14 +4,28 @@ SecureHeaders supports `Secure`, `HttpOnly` and [`SameSite`](https://tools.ietf. 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            __Note__: Regardless of the configuration specified, Secure cookies are only enabled for HTTPS requests.
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
      
 7 
     | 
    
         
            +
            #### Defaults
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            By default, all cookies will get both `Secure`, `HttpOnly`, and `SameSite=Lax`.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
            config.cookies = {
         
     | 
| 
      
 13 
     | 
    
         
            +
              secure: true, # defaults to true but will be a no op on non-HTTPS requests
         
     | 
| 
      
 14 
     | 
    
         
            +
              httponly: true, # defaults to true
         
     | 
| 
      
 15 
     | 
    
         
            +
              samesite: {  # defaults to set `SameSite=Lax`
         
     | 
| 
      
 16 
     | 
    
         
            +
                lax: true
         
     | 
| 
      
 17 
     | 
    
         
            +
              }
         
     | 
| 
      
 18 
     | 
    
         
            +
            }
         
     | 
| 
      
 19 
     | 
    
         
            +
            ```
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       7 
21 
     | 
    
         
             
            #### Boolean-based configuration
         
     | 
| 
       8 
22 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
            Boolean-based configuration is intended to globally enable or disable a specific cookie attribute.
         
     | 
| 
      
 23 
     | 
    
         
            +
            Boolean-based configuration is intended to globally enable or disable a specific cookie attribute. *Note: As of 4.0, you must use OPT_OUT rather than false to opt out of the defaults.*
         
     | 
| 
       10 
24 
     | 
    
         | 
| 
       11 
25 
     | 
    
         
             
            ```ruby
         
     | 
| 
       12 
26 
     | 
    
         
             
            config.cookies = {
         
     | 
| 
       13 
27 
     | 
    
         
             
              secure: true, # mark all cookies as Secure
         
     | 
| 
       14 
     | 
    
         
            -
              httponly:  
     | 
| 
      
 28 
     | 
    
         
            +
              httponly: OPT_OUT, # do not mark any cookies as HttpOnly
         
     | 
| 
       15 
29 
     | 
    
         
             
            }
         
     | 
| 
       16 
30 
     | 
    
         
             
            ```
         
     | 
| 
       17 
31 
     | 
    
         | 
| 
         @@ -38,14 +52,13 @@ config.cookies = { 
     | 
|
| 
       38 
52 
     | 
    
         
             
            }
         
     | 
| 
       39 
53 
     | 
    
         
             
            ```
         
     | 
| 
       40 
54 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
            `Strict 
     | 
| 
      
 55 
     | 
    
         
            +
            `Strict` and `Lax` enforcement modes can also be specified using a Hash.
         
     | 
| 
       42 
56 
     | 
    
         | 
| 
       43 
57 
     | 
    
         
             
            ```ruby
         
     | 
| 
       44 
58 
     | 
    
         
             
            config.cookies = {
         
     | 
| 
       45 
59 
     | 
    
         
             
              samesite: {
         
     | 
| 
       46 
60 
     | 
    
         
             
                strict: { only: ['_rails_session'] },
         
     | 
| 
       47 
     | 
    
         
            -
                lax: { only: ['_guest'] } 
     | 
| 
       48 
     | 
    
         
            -
                none: { only: ['_tracking'] },
         
     | 
| 
      
 61 
     | 
    
         
            +
                lax: { only: ['_guest'] }
         
     | 
| 
       49 
62 
     | 
    
         
             
              }
         
     | 
| 
       50 
63 
     | 
    
         
             
            }
         
     | 
| 
       51 
64 
     | 
    
         
             
            ```
         
     | 
    
        data/lib/secure_headers.rb
    CHANGED
    
    | 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            require "secure_headers/configuration"
         
     | 
| 
       2 
3 
     | 
    
         
             
            require "secure_headers/hash_helper"
         
     | 
| 
       3 
4 
     | 
    
         
             
            require "secure_headers/headers/cookie"
         
     | 
| 
         @@ -11,7 +12,6 @@ require "secure_headers/headers/x_download_options" 
     | 
|
| 
       11 
12 
     | 
    
         
             
            require "secure_headers/headers/x_permitted_cross_domain_policies"
         
     | 
| 
       12 
13 
     | 
    
         
             
            require "secure_headers/headers/referrer_policy"
         
     | 
| 
       13 
14 
     | 
    
         
             
            require "secure_headers/headers/clear_site_data"
         
     | 
| 
       14 
     | 
    
         
            -
            require "secure_headers/headers/expect_certificate_transparency"
         
     | 
| 
       15 
15 
     | 
    
         
             
            require "secure_headers/middleware"
         
     | 
| 
       16 
16 
     | 
    
         
             
            require "secure_headers/railtie"
         
     | 
| 
       17 
17 
     | 
    
         
             
            require "secure_headers/view_helper"
         
     | 
| 
         @@ -52,7 +52,6 @@ module SecureHeaders 
     | 
|
| 
       52 
52 
     | 
    
         
             
              CSP = ContentSecurityPolicy
         
     | 
| 
       53 
53 
     | 
    
         | 
| 
       54 
54 
     | 
    
         
             
              ALL_HEADER_CLASSES = [
         
     | 
| 
       55 
     | 
    
         
            -
                ExpectCertificateTransparency,
         
     | 
| 
       56 
55 
     | 
    
         
             
                ClearSiteData,
         
     | 
| 
       57 
56 
     | 
    
         
             
                ContentSecurityPolicyConfig,
         
     | 
| 
       58 
57 
     | 
    
         
             
                ContentSecurityPolicyReportOnlyConfig,
         
     | 
| 
         @@ -1,4 +1,5 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "yaml"
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            module SecureHeaders
         
     | 
| 
       4 
5 
     | 
    
         
             
              class Configuration
         
     | 
| 
         @@ -116,7 +117,7 @@ module SecureHeaders 
     | 
|
| 
       116 
117 
     | 
    
         | 
| 
       117 
118 
     | 
    
         
             
                attr_writer :hsts, :x_frame_options, :x_content_type_options,
         
     | 
| 
       118 
119 
     | 
    
         
             
                  :x_xss_protection, :x_download_options, :x_permitted_cross_domain_policies,
         
     | 
| 
       119 
     | 
    
         
            -
                  :referrer_policy, :clear_site_data 
     | 
| 
      
 120 
     | 
    
         
            +
                  :referrer_policy, :clear_site_data
         
     | 
| 
       120 
121 
     | 
    
         | 
| 
       121 
122 
     | 
    
         
             
                attr_reader :cached_headers, :csp, :cookies, :csp_report_only, :hpkp, :hpkp_report_host
         
     | 
| 
       122 
123 
     | 
    
         | 
| 
         @@ -143,7 +144,6 @@ module SecureHeaders 
     | 
|
| 
       143 
144 
     | 
    
         
             
                  @x_frame_options = nil
         
     | 
| 
       144 
145 
     | 
    
         
             
                  @x_permitted_cross_domain_policies = nil
         
     | 
| 
       145 
146 
     | 
    
         
             
                  @x_xss_protection = nil
         
     | 
| 
       146 
     | 
    
         
            -
                  @expect_certificate_transparency = nil
         
     | 
| 
       147 
147 
     | 
    
         | 
| 
       148 
148 
     | 
    
         
             
                  self.hpkp = OPT_OUT
         
     | 
| 
       149 
149 
     | 
    
         
             
                  self.referrer_policy = OPT_OUT
         
     | 
| 
         @@ -169,7 +169,6 @@ module SecureHeaders 
     | 
|
| 
       169 
169 
     | 
    
         
             
                  copy.x_download_options = @x_download_options
         
     | 
| 
       170 
170 
     | 
    
         
             
                  copy.x_permitted_cross_domain_policies = @x_permitted_cross_domain_policies
         
     | 
| 
       171 
171 
     | 
    
         
             
                  copy.clear_site_data = @clear_site_data
         
     | 
| 
       172 
     | 
    
         
            -
                  copy.expect_certificate_transparency = @expect_certificate_transparency
         
     | 
| 
       173 
172 
     | 
    
         
             
                  copy.referrer_policy = @referrer_policy
         
     | 
| 
       174 
173 
     | 
    
         
             
                  copy.hpkp = @hpkp
         
     | 
| 
       175 
174 
     | 
    
         
             
                  copy.hpkp_report_host = @hpkp_report_host
         
     | 
| 
         @@ -202,14 +201,12 @@ module SecureHeaders 
     | 
|
| 
       202 
201 
     | 
    
         
             
                  XDownloadOptions.validate_config!(@x_download_options)
         
     | 
| 
       203 
202 
     | 
    
         
             
                  XPermittedCrossDomainPolicies.validate_config!(@x_permitted_cross_domain_policies)
         
     | 
| 
       204 
203 
     | 
    
         
             
                  ClearSiteData.validate_config!(@clear_site_data)
         
     | 
| 
       205 
     | 
    
         
            -
                  ExpectCertificateTransparency.validate_config!(@expect_certificate_transparency)
         
     | 
| 
       206 
204 
     | 
    
         
             
                  PublicKeyPins.validate_config!(@hpkp)
         
     | 
| 
       207 
205 
     | 
    
         
             
                  Cookie.validate_config!(@cookies)
         
     | 
| 
       208 
206 
     | 
    
         
             
                end
         
     | 
| 
       209 
207 
     | 
    
         | 
| 
       210 
208 
     | 
    
         
             
                def secure_cookies=(secure_cookies)
         
     | 
| 
       211 
     | 
    
         
            -
                   
     | 
| 
       212 
     | 
    
         
            -
                  @cookies = (@cookies || {}).merge(secure: secure_cookies)
         
     | 
| 
      
 209 
     | 
    
         
            +
                  raise ArgumentError, "#{Kernel.caller.first}: `#secure_cookies=` is no longer supported. Please use `#cookies=` to configure secure cookies instead."
         
     | 
| 
       213 
210 
     | 
    
         
             
                end
         
     | 
| 
       214 
211 
     | 
    
         | 
| 
       215 
212 
     | 
    
         
             
                def csp=(new_csp)
         
     | 
| 
         @@ -217,10 +214,8 @@ module SecureHeaders 
     | 
|
| 
       217 
214 
     | 
    
         
             
                    @csp = new_csp.dup
         
     | 
| 
       218 
215 
     | 
    
         
             
                  else
         
     | 
| 
       219 
216 
     | 
    
         
             
                    if new_csp[:report_only]
         
     | 
| 
       220 
     | 
    
         
            -
                      #  
     | 
| 
       221 
     | 
    
         
            -
                       
     | 
| 
       222 
     | 
    
         
            -
                      @csp = OPT_OUT
         
     | 
| 
       223 
     | 
    
         
            -
                      self.csp_report_only = new_csp
         
     | 
| 
      
 217 
     | 
    
         
            +
                      # invalid configuration implies that CSPRO should be set, CSP should not - so opt out
         
     | 
| 
      
 218 
     | 
    
         
            +
                      raise ArgumentError, "#{Kernel.caller.first}: `#csp=` was supplied a config with report_only: true. Use #csp_report_only="
         
     | 
| 
       224 
219 
     | 
    
         
             
                    else
         
     | 
| 
       225 
220 
     | 
    
         
             
                      @csp = ContentSecurityPolicyConfig.new(new_csp)
         
     | 
| 
       226 
221 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -247,11 +242,6 @@ module SecureHeaders 
     | 
|
| 
       247 
242 
     | 
    
         
             
                      end
         
     | 
| 
       248 
243 
     | 
    
         
             
                    end
         
     | 
| 
       249 
244 
     | 
    
         
             
                  end
         
     | 
| 
       250 
     | 
    
         
            -
             
     | 
| 
       251 
     | 
    
         
            -
                  if !@csp_report_only.opt_out? && @csp.to_h == ContentSecurityPolicyConfig::DEFAULT
         
     | 
| 
       252 
     | 
    
         
            -
                    Kernel.warn "#{Kernel.caller.first}: [DEPRECATION] `#csp_report_only=` was configured before `#csp=`. It is assumed you intended to opt out of `#csp=` so be sure to add `config.csp = SecureHeaders::OPT_OUT` to your config. Ensure that #csp_report_only is configured after #csp="
         
     | 
| 
       253 
     | 
    
         
            -
                    @csp = OPT_OUT
         
     | 
| 
       254 
     | 
    
         
            -
                  end
         
     | 
| 
       255 
245 
     | 
    
         
             
                end
         
     | 
| 
       256 
246 
     | 
    
         | 
| 
       257 
247 
     | 
    
         
             
                protected
         
     | 
| 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            module SecureHeaders
         
     | 
| 
       2 
3 
     | 
    
         
             
              class ClearSiteDataConfigError < StandardError; end
         
     | 
| 
       3 
4 
     | 
    
         
             
              class ClearSiteData
         
     | 
| 
         @@ -16,7 +17,7 @@ module SecureHeaders 
     | 
|
| 
       16 
17 
     | 
    
         
             
                  # Public: make an Clear-Site-Data header name, value pair
         
     | 
| 
       17 
18 
     | 
    
         
             
                  #
         
     | 
| 
       18 
19 
     | 
    
         
             
                  # Returns nil if not configured, returns header name and value if configured.
         
     | 
| 
       19 
     | 
    
         
            -
                  def make_header(config=nil)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def make_header(config = nil)
         
     | 
| 
       20 
21 
     | 
    
         
             
                    case config
         
     | 
| 
       21 
22 
     | 
    
         
             
                    when nil, OPT_OUT, []
         
     | 
| 
       22 
23 
     | 
    
         
             
                      # noop
         
     | 
| 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
            require_relative  
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative "policy_management"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative "content_security_policy_config"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "useragent"
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module SecureHeaders
         
     | 
| 
       6 
7 
     | 
    
         
             
              class ContentSecurityPolicy
         
     | 
| 
         @@ -54,18 +55,12 @@ module SecureHeaders 
     | 
|
| 
       54 
55 
     | 
    
         | 
| 
       55 
56 
     | 
    
         
             
                private
         
     | 
| 
       56 
57 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
                # frame-src is deprecated, child-src is being implemented. They are
         
     | 
| 
       58 
     | 
    
         
            -
                # very similar and in most cases, the same value can be used for both.
         
     | 
| 
       59 
58 
     | 
    
         
             
                def normalize_child_frame_src
         
     | 
| 
       60 
59 
     | 
    
         
             
                  if @config.frame_src && @config.child_src && @config.frame_src != @config.child_src
         
     | 
| 
       61 
     | 
    
         
            -
                     
     | 
| 
      
 60 
     | 
    
         
            +
                    raise ArgumentError, "#{Kernel.caller.first}: both :child_src and :frame_src supplied and do not match. This can lead to inconsistent behavior across browsers."
         
     | 
| 
       62 
61 
     | 
    
         
             
                  end
         
     | 
| 
       63 
62 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
                   
     | 
| 
       65 
     | 
    
         
            -
                    @config.child_src || @config.frame_src
         
     | 
| 
       66 
     | 
    
         
            -
                  else
         
     | 
| 
       67 
     | 
    
         
            -
                    @config.frame_src || @config.child_src
         
     | 
| 
       68 
     | 
    
         
            -
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  @config.frame_src || @config.child_src
         
     | 
| 
       69 
64 
     | 
    
         
             
                end
         
     | 
| 
       70 
65 
     | 
    
         | 
| 
       71 
66 
     | 
    
         
             
                # Private: converts the config object into a string representing a policy.
         
     | 
| 
         @@ -80,55 +75,20 @@ module SecureHeaders 
     | 
|
| 
       80 
75 
     | 
    
         
             
                    case DIRECTIVE_VALUE_TYPES[directive_name]
         
     | 
| 
       81 
76 
     | 
    
         
             
                    when :boolean
         
     | 
| 
       82 
77 
     | 
    
         
             
                      symbol_to_hyphen_case(directive_name) if @config.directive_value(directive_name)
         
     | 
| 
       83 
     | 
    
         
            -
                    when : 
     | 
| 
       84 
     | 
    
         
            -
                       
     | 
| 
       85 
     | 
    
         
            -
                     
     | 
| 
       86 
     | 
    
         
            -
                       
     | 
| 
       87 
     | 
    
         
            -
                    when :source_list
         
     | 
| 
       88 
     | 
    
         
            -
                      build_source_list_directive(directive_name)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    when :string
         
     | 
| 
      
 79 
     | 
    
         
            +
                      [symbol_to_hyphen_case(directive_name), @config.directive_value(directive_name)].join(" ")
         
     | 
| 
      
 80 
     | 
    
         
            +
                    else
         
     | 
| 
      
 81 
     | 
    
         
            +
                      build_directive(directive_name)
         
     | 
| 
       89 
82 
     | 
    
         
             
                    end
         
     | 
| 
       90 
83 
     | 
    
         
             
                  end.compact.join("; ")
         
     | 
| 
       91 
84 
     | 
    
         
             
                end
         
     | 
| 
       92 
85 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
                def build_sandbox_list_directive(directive)
         
     | 
| 
       94 
     | 
    
         
            -
                  return unless sandbox_list = @config.directive_value(directive)
         
     | 
| 
       95 
     | 
    
         
            -
                  max_strict_policy = case sandbox_list
         
     | 
| 
       96 
     | 
    
         
            -
                  when Array
         
     | 
| 
       97 
     | 
    
         
            -
                    sandbox_list.empty?
         
     | 
| 
       98 
     | 
    
         
            -
                  when true
         
     | 
| 
       99 
     | 
    
         
            -
                    true
         
     | 
| 
       100 
     | 
    
         
            -
                  else
         
     | 
| 
       101 
     | 
    
         
            -
                    false
         
     | 
| 
       102 
     | 
    
         
            -
                  end
         
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
                  # A maximally strict sandbox policy is just the `sandbox` directive,
         
     | 
| 
       105 
     | 
    
         
            -
                  # whith no configuraiton values.
         
     | 
| 
       106 
     | 
    
         
            -
                  if max_strict_policy
         
     | 
| 
       107 
     | 
    
         
            -
                    symbol_to_hyphen_case(directive)
         
     | 
| 
       108 
     | 
    
         
            -
                  elsif sandbox_list && sandbox_list.any?
         
     | 
| 
       109 
     | 
    
         
            -
                    [
         
     | 
| 
       110 
     | 
    
         
            -
                      symbol_to_hyphen_case(directive),
         
     | 
| 
       111 
     | 
    
         
            -
                      sandbox_list.uniq
         
     | 
| 
       112 
     | 
    
         
            -
                    ].join(" ")
         
     | 
| 
       113 
     | 
    
         
            -
                  end
         
     | 
| 
       114 
     | 
    
         
            -
                end
         
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
                def build_media_type_list_directive(directive)
         
     | 
| 
       117 
     | 
    
         
            -
                  return unless media_type_list = @config.directive_value(directive)
         
     | 
| 
       118 
     | 
    
         
            -
                  if media_type_list && media_type_list.any?
         
     | 
| 
       119 
     | 
    
         
            -
                    [
         
     | 
| 
       120 
     | 
    
         
            -
                      symbol_to_hyphen_case(directive),
         
     | 
| 
       121 
     | 
    
         
            -
                      media_type_list.uniq
         
     | 
| 
       122 
     | 
    
         
            -
                    ].join(" ")
         
     | 
| 
       123 
     | 
    
         
            -
                  end
         
     | 
| 
       124 
     | 
    
         
            -
                end
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
86 
     | 
    
         
             
                # Private: builds a string that represents one directive in a minified form.
         
     | 
| 
       127 
87 
     | 
    
         
             
                #
         
     | 
| 
       128 
88 
     | 
    
         
             
                # directive_name - a symbol representing the various ALL_DIRECTIVES
         
     | 
| 
       129 
89 
     | 
    
         
             
                #
         
     | 
| 
       130 
90 
     | 
    
         
             
                # Returns a string representing a directive.
         
     | 
| 
       131 
     | 
    
         
            -
                def  
     | 
| 
      
 91 
     | 
    
         
            +
                def build_directive(directive)
         
     | 
| 
       132 
92 
     | 
    
         
             
                  source_list = case directive
         
     | 
| 
       133 
93 
     | 
    
         
             
                  when :child_src
         
     | 
| 
       134 
94 
     | 
    
         
             
                    if supported_directives.include?(:child_src)
         
     | 
| 
         @@ -142,14 +102,8 @@ module SecureHeaders 
     | 
|
| 
       142 
102 
     | 
    
         
             
                    @config.directive_value(directive)
         
     | 
| 
       143 
103 
     | 
    
         
             
                  end
         
     | 
| 
       144 
104 
     | 
    
         
             
                  return unless source_list && source_list.any?
         
     | 
| 
       145 
     | 
    
         
            -
                  normalized_source_list = minify_source_list(directive, source_list) 
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
                  if normalized_source_list =~ /(\n|;)/
         
     | 
| 
       148 
     | 
    
         
            -
                    Kernel.warn("#{directive} contains a #{$1} in #{normalized_source_list.inspect} which will raise an error in future versions. It has been replaced with a blank space.")
         
     | 
| 
       149 
     | 
    
         
            -
                  end
         
     | 
| 
       150 
     | 
    
         
            -
                  escaped_source_list = normalized_source_list.gsub(/[\n;]/, " ")
         
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
                  [symbol_to_hyphen_case(directive), escaped_source_list].join(" ").strip
         
     | 
| 
      
 105 
     | 
    
         
            +
                  normalized_source_list = minify_source_list(directive, source_list)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  [symbol_to_hyphen_case(directive), normalized_source_list].join(" ")
         
     | 
| 
       153 
107 
     | 
    
         
             
                end
         
     | 
| 
       154 
108 
     | 
    
         | 
| 
       155 
109 
     | 
    
         
             
                # If a directive contains *, all other values are omitted.
         
     | 
| 
         @@ -270,7 +224,7 @@ module SecureHeaders 
     | 
|
| 
       270 
224 
     | 
    
         
             
                end
         
     | 
| 
       271 
225 
     | 
    
         | 
| 
       272 
226 
     | 
    
         
             
                def symbol_to_hyphen_case(sym)
         
     | 
| 
       273 
     | 
    
         
            -
                  sym.to_s.tr( 
     | 
| 
      
 227 
     | 
    
         
            +
                  sym.to_s.tr("_", "-")
         
     | 
| 
       274 
228 
     | 
    
         
             
                end
         
     | 
| 
       275 
229 
     | 
    
         
             
              end
         
     | 
| 
       276 
230 
     | 
    
         
             
            end
         
     |