secure_headers 6.3.4 → 7.3.0

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -2
  3. data/Gemfile +2 -0
  4. data/README.md +81 -15
  5. data/lib/secure_headers/configuration.rb +64 -13
  6. data/lib/secure_headers/headers/clear_site_data.rb +31 -33
  7. data/lib/secure_headers/headers/content_security_policy.rb +80 -46
  8. data/lib/secure_headers/headers/content_security_policy_config.rb +17 -58
  9. data/lib/secure_headers/headers/cookie.rb +4 -6
  10. data/lib/secure_headers/headers/expect_certificate_transparency.rb +20 -22
  11. data/lib/secure_headers/headers/policy_management.rb +66 -18
  12. data/lib/secure_headers/headers/referrer_policy.rb +20 -22
  13. data/lib/secure_headers/headers/reporting_endpoints.rb +54 -0
  14. data/lib/secure_headers/headers/strict_transport_security.rb +13 -15
  15. data/lib/secure_headers/headers/x_content_type_options.rb +14 -16
  16. data/lib/secure_headers/headers/x_download_options.rb +14 -16
  17. data/lib/secure_headers/headers/x_frame_options.rb +14 -16
  18. data/lib/secure_headers/headers/x_permitted_cross_domain_policies.rb +14 -16
  19. data/lib/secure_headers/headers/x_xss_protection.rb +14 -16
  20. data/lib/secure_headers/middleware.rb +11 -7
  21. data/lib/secure_headers/railtie.rb +11 -8
  22. data/lib/secure_headers/task_helper.rb +65 -0
  23. data/lib/secure_headers/version.rb +1 -1
  24. data/lib/secure_headers/view_helper.rb +7 -6
  25. data/lib/secure_headers.rb +26 -2
  26. data/lib/tasks/tasks.rake +4 -53
  27. data/secure_headers.gemspec +19 -7
  28. metadata +38 -70
  29. data/.github/ISSUE_TEMPLATE.md +0 -41
  30. data/.github/PULL_REQUEST_TEMPLATE.md +0 -20
  31. data/.github/workflows/build.yml +0 -24
  32. data/.github/workflows/github-release.yml +0 -28
  33. data/.gitignore +0 -13
  34. data/.rspec +0 -3
  35. data/.rubocop.yml +0 -4
  36. data/.ruby-gemset +0 -1
  37. data/.ruby-version +0 -1
  38. data/CODE_OF_CONDUCT.md +0 -46
  39. data/CONTRIBUTING.md +0 -41
  40. data/Guardfile +0 -13
  41. data/Rakefile +0 -32
  42. data/docs/cookies.md +0 -65
  43. data/docs/hashes.md +0 -64
  44. data/docs/named_overrides_and_appends.md +0 -104
  45. data/docs/per_action_configuration.md +0 -139
  46. data/docs/sinatra.md +0 -25
  47. data/docs/upgrading-to-3-0.md +0 -42
  48. data/docs/upgrading-to-4-0.md +0 -35
  49. data/docs/upgrading-to-5-0.md +0 -15
  50. data/docs/upgrading-to-6-0.md +0 -50
  51. data/spec/lib/secure_headers/configuration_spec.rb +0 -121
  52. data/spec/lib/secure_headers/headers/clear_site_data_spec.rb +0 -87
  53. data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +0 -190
  54. data/spec/lib/secure_headers/headers/cookie_spec.rb +0 -179
  55. data/spec/lib/secure_headers/headers/expect_certificate_transparency_spec.rb +0 -42
  56. data/spec/lib/secure_headers/headers/policy_management_spec.rb +0 -264
  57. data/spec/lib/secure_headers/headers/referrer_policy_spec.rb +0 -91
  58. data/spec/lib/secure_headers/headers/strict_transport_security_spec.rb +0 -33
  59. data/spec/lib/secure_headers/headers/x_content_type_options_spec.rb +0 -31
  60. data/spec/lib/secure_headers/headers/x_download_options_spec.rb +0 -29
  61. data/spec/lib/secure_headers/headers/x_frame_options_spec.rb +0 -36
  62. data/spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb +0 -48
  63. data/spec/lib/secure_headers/headers/x_xss_protection_spec.rb +0 -47
  64. data/spec/lib/secure_headers/middleware_spec.rb +0 -117
  65. data/spec/lib/secure_headers/view_helpers_spec.rb +0 -191
  66. data/spec/lib/secure_headers_spec.rb +0 -516
  67. data/spec/spec_helper.rb +0 -64
@@ -1,41 +0,0 @@
1
- # Feature Requests
2
-
3
- ## Adding a new header
4
-
5
- Generally, adding a new header is always OK.
6
-
7
- * Is the header supported by any user agent? If so, which?
8
- * What does it do?
9
- * What are the valid values for the header?
10
- * Where does the specification live?
11
-
12
- ## Adding a new CSP directive
13
-
14
- * Is the directive supported by any user agent? If so, which?
15
- * What does it do?
16
- * What are the valid values for the directive?
17
-
18
- ---
19
-
20
- # Bugs
21
-
22
- Console errors and deprecation warnings are considered bugs that should be addressed with more precise UA sniffing. Bugs caused by incorrect or invalid UA sniffing are also bugs.
23
-
24
- ### Expected outcome
25
-
26
- Describe what you expected to happen
27
-
28
- 1. I configure CSP to do X
29
- 1. When I inspect the response headers, the CSP should have included X
30
-
31
- ### Actual outcome
32
-
33
- 1. The generated policy did not include X
34
-
35
- ### Config
36
-
37
- Please provide the configuration (`SecureHeaders::Configuration.default`) you are using including any overrides (`SecureHeaders::Configuration.override`).
38
-
39
- ### Generated headers
40
-
41
- Provide a sample response containing the headers
@@ -1,20 +0,0 @@
1
- ## All PRs:
2
-
3
- * [ ] Has tests
4
- * [ ] Documentation updated
5
-
6
- ## Adding a new header
7
-
8
- Generally, adding a new header is always OK.
9
-
10
- * Is the header supported by any user agent? If so, which?
11
- * What does it do?
12
- * What are the valid values for the header?
13
- * Where does the specification live?
14
-
15
- ## Adding a new CSP directive
16
-
17
- * Is the directive supported by any user agent? If so, which?
18
- * What does it do?
19
- * What are the valid values for the directive?
20
-
@@ -1,24 +0,0 @@
1
- name: Build + Test
2
- on: [pull_request]
3
-
4
- jobs:
5
- build:
6
- name: Build + Test
7
- runs-on: ubuntu-latest
8
- strategy:
9
- matrix:
10
- ruby: [ '2.5', '2.6', '2.7', '3.0' ]
11
-
12
- steps:
13
- - uses: actions/checkout@v2
14
- - name: Set up Ruby ${{ matrix.ruby }}
15
- uses: ruby/setup-ruby@v1
16
- with:
17
- ruby-version: ${{ matrix.ruby }}
18
- - name: Build and test with Rake
19
- run: |
20
- gem install bundler
21
- bundle install --jobs 4 --retry 3 --without guard
22
- bundle exec rspec spec
23
- bundle exec rubocop
24
-
@@ -1,28 +0,0 @@
1
- name: GitHub Release
2
-
3
- on:
4
- push:
5
- tags:
6
- - v*
7
-
8
- jobs:
9
- Publish:
10
- permissions:
11
- contents: write
12
- runs-on: ubuntu-latest
13
- if: startsWith(github.ref, 'refs/tags/v')
14
- steps:
15
- - name: Calculate release name
16
- run: |
17
- GITHUB_REF=${{ github.ref }}
18
- RELEASE_NAME=${GITHUB_REF#"refs/tags/"}
19
- echo "RELEASE_NAME=${RELEASE_NAME}" >> $GITHUB_ENV
20
- - name: Publish release
21
- uses: actions/create-release@v1
22
- env:
23
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24
- with:
25
- tag_name: ${{ github.ref }}
26
- release_name: ${{ env.RELEASE_NAME }}
27
- draft: false
28
- prerelease: false
data/.gitignore DELETED
@@ -1,13 +0,0 @@
1
- *.gem
2
- *.DS_STORE
3
- *.rbc
4
- .bundle
5
- .config
6
- .yardoc
7
- *.log
8
- Gemfile.lock
9
- _yardoc
10
- coverage
11
- pkg
12
- rdoc
13
- spec/reports
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --order rand
2
- --warnings
3
- --format progress
data/.rubocop.yml DELETED
@@ -1,4 +0,0 @@
1
- inherit_gem:
2
- rubocop-github:
3
- - config/default.yml
4
- require: rubocop-performance
data/.ruby-gemset DELETED
@@ -1 +0,0 @@
1
- secureheaders
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.6.6
data/CODE_OF_CONDUCT.md DELETED
@@ -1,46 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
-
7
- ## Our Standards
8
-
9
- Examples of behavior that contributes to creating a positive environment include:
10
-
11
- * Using welcoming and inclusive language
12
- * Being respectful of differing viewpoints and experiences
13
- * Gracefully accepting constructive criticism
14
- * Focusing on what is best for the community
15
- * Showing empathy towards other community members
16
-
17
- Examples of unacceptable behavior by participants include:
18
-
19
- * The use of sexualized language or imagery and unwelcome sexual attention or advances
20
- * Trolling, insulting/derogatory comments, and personal or political attacks
21
- * Public or private harassment
22
- * Publishing others' private information, such as a physical or electronic address, without explicit permission
23
- * Other conduct which could reasonably be considered inappropriate in a professional setting
24
-
25
- ## Our Responsibilities
26
-
27
- Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28
-
29
- Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30
-
31
- ## Scope
32
-
33
- This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34
-
35
- ## Enforcement
36
-
37
- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at neil.matatall@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38
-
39
- Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40
-
41
- ## Attribution
42
-
43
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44
-
45
- [homepage]: http://contributor-covenant.org
46
- [version]: http://contributor-covenant.org/version/1/4/
data/CONTRIBUTING.md DELETED
@@ -1,41 +0,0 @@
1
- ## Contributing
2
-
3
- [fork]: https://github.com/twitter/secureheaders/fork
4
- [pr]: https://github.com/twitter/secureheaders/compare
5
- [style]: https://github.com/styleguide/ruby
6
- [code-of-conduct]: CODE_OF_CONDUCT.md
7
-
8
- Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.
9
-
10
- Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms.
11
-
12
- ## Submitting a pull request
13
-
14
- 0. [Fork][fork] and clone the repository
15
- 0. Configure and install the dependencies: `bundle install`
16
- 0. Make sure the tests pass on your machine: `bundle exec rspec spec`
17
- 0. Create a new branch: `git checkout -b my-branch-name`
18
- 0. Make your change, add tests, and make sure the tests still pass and that no warnings are raised
19
- 0. Push to your fork and [submit a pull request][pr]
20
- 0. Pat your self on the back and wait for your pull request to be reviewed and merged.
21
-
22
- Here are a few things you can do that will increase the likelihood of your pull request being accepted:
23
-
24
- - Write tests.
25
- - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
26
- - Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
27
-
28
- ## Releasing
29
-
30
- 0. Ensure CI is green
31
- 0. Pull the latest code
32
- 0. Increment the version
33
- 0. Run `gem build secure_headers.gemspec`
34
- 0. Bump the Gemfile and Gemfile.lock versions for an app which relies on this gem
35
- 0. Test behavior locally, branch deploy, whatever needs to happen
36
- 0. Run `bundle exec rake release`
37
-
38
- ## Resources
39
-
40
- - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
41
- - [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
data/Guardfile DELETED
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
- guard :rspec, cmd: "bundle exec rspec", all_on_start: true, all_after_pass: true do
3
- require "guard/rspec/dsl"
4
- dsl = Guard::RSpec::Dsl.new(self)
5
-
6
- # RSpec files
7
- rspec = dsl.rspec
8
- watch(rspec.spec_helper) { rspec.spec_dir }
9
- watch(rspec.spec_support) { rspec.spec_dir }
10
- watch(rspec.spec_files)
11
-
12
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
13
- end
data/Rakefile DELETED
@@ -1,32 +0,0 @@
1
- #!/usr/bin/env rake
2
- # frozen_string_literal: true
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
- require "net/http"
6
- require "net/https"
7
-
8
- RSpec::Core::RakeTask.new
9
-
10
- begin
11
- require "rdoc/task"
12
- rescue LoadError
13
- require "rdoc/rdoc"
14
- require "rake/rdoctask"
15
- RDoc::Task = Rake::RDocTask
16
- end
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
-
25
- RDoc::Task.new(:rdoc) do |rdoc|
26
- rdoc.rdoc_dir = "rdoc"
27
- rdoc.title = "SecureHeaders"
28
- rdoc.options << "--line-numbers"
29
- rdoc.rdoc_files.include("lib/**/*.rb")
30
- end
31
-
32
- task default: [:spec, :rubocop]
data/docs/cookies.md DELETED
@@ -1,65 +0,0 @@
1
- ## Cookies
2
-
3
- SecureHeaders supports `Secure`, `HttpOnly` and [`SameSite`](https://tools.ietf.org/html/draft-west-first-party-cookies-07) cookies. These can be defined in the form of a boolean, or as a Hash for more refined configuration.
4
-
5
- __Note__: Regardless of the configuration specified, Secure cookies are only enabled for HTTPS requests.
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
-
21
- #### Boolean-based configuration
22
-
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.*
24
-
25
- ```ruby
26
- config.cookies = {
27
- secure: true, # mark all cookies as Secure
28
- httponly: SecureHeaders::OPT_OUT, # do not mark any cookies as HttpOnly
29
- }
30
- ```
31
-
32
- #### Hash-based configuration
33
-
34
- Hash-based configuration allows for fine-grained control.
35
-
36
- ```ruby
37
- config.cookies = {
38
- secure: { except: ['_guest'] }, # mark all but the `_guest` cookie as Secure
39
- httponly: { only: ['_rails_session'] }, # only mark the `_rails_session` cookie as HttpOnly
40
- }
41
- ```
42
-
43
- #### SameSite cookie configuration
44
-
45
- SameSite cookies permit either `Strict` or `Lax` enforcement mode options.
46
-
47
- ```ruby
48
- config.cookies = {
49
- samesite: {
50
- strict: true # mark all cookies as SameSite=Strict
51
- }
52
- }
53
- ```
54
-
55
- `Strict`, `Lax`, and `None` enforcement modes can also be specified using a Hash.
56
-
57
- ```ruby
58
- config.cookies = {
59
- samesite: {
60
- strict: { only: ['session_id_duplicate'] },
61
- lax: { only: ['_guest', '_rails_session', 'device_id'] },
62
- none: { only: ['_tracking', 'saml_cookie', 'session_id'] },
63
- }
64
- }
65
- ```
data/docs/hashes.md DELETED
@@ -1,64 +0,0 @@
1
- ## Hash
2
-
3
- `script`/`style-src` hashes can be used to whitelist inline content that is static. This has the benefit of allowing inline content without opening up the possibility of dynamic javascript like you would with a `nonce`.
4
-
5
- You can add hash sources directly to your policy :
6
-
7
- ```ruby
8
- ::SecureHeaders::Configuration.default do |config|
9
- config.csp = {
10
- default_src: %w('self')
11
-
12
- # this is a made up value but browsers will show the expected hash in the console.
13
- script_src: %w(sha256-123456)
14
- }
15
- end
16
- ```
17
-
18
- You can also use the automated inline script detection/collection/computation of hash source values in your app.
19
-
20
- ```bash
21
- rake secure_headers:generate_hashes
22
- ```
23
-
24
- This will generate a file (`config/secure_headers_generated_hashes.yml` by default, you can override by setting `ENV["secure_headers_generated_hashes_file"]`) containing a mapping of file names with the array of hash values found on that page. When ActionView renders a given file, we check if there are any known hashes for that given file. If so, they are added as values to the header.
25
-
26
- ```yaml
27
- ---
28
- scripts:
29
- app/views/asdfs/index.html.erb:
30
- - "'sha256-yktKiAsZWmc8WpOyhnmhQoDf9G2dAZvuBBC+V0LGQhg='"
31
- styles:
32
- app/views/asdfs/index.html.erb:
33
- - "'sha256-SLp6LO3rrKDJwsG9uJUxZapb4Wp2Zhj6Bu3l+d9rnAY='"
34
- - "'sha256-HSGHqlRoKmHAGTAJ2Rq0piXX4CnEbOl1ArNd6ejp2TE='"
35
- ```
36
-
37
- ##### Helpers
38
-
39
- **This will not compute dynamic hashes** by design. The output of both helpers will be a plain `script`/`style` tag without modification and the known hashes for a given file will be added to `script-src`/`style-src` when `hashed_javascript_tag` and `hashed_style_tag` are used. You can use `raise_error_on_unrecognized_hash = true` to be extra paranoid that you have precomputed hash values for all of your inline content. By default, this will raise an error in non-production environments.
40
-
41
- ```erb
42
- <%= hashed_style_tag do %>
43
- body {
44
- background-color: black;
45
- }
46
- <% end %>
47
-
48
- <%= hashed_style_tag do %>
49
- body {
50
- font-size: 30px;
51
- font-color: green;
52
- }
53
- <% end %>
54
-
55
- <%= hashed_javascript_tag do %>
56
- console.log(1)
57
- <% end %>
58
- ```
59
-
60
- ```
61
- Content-Security-Policy: ...
62
- script-src 'sha256-yktKiAsZWmc8WpOyhnmhQoDf9G2dAZvuBBC+V0LGQhg=' ... ;
63
- style-src 'sha256-SLp6LO3rrKDJwsG9uJUxZapb4Wp2Zhj6Bu3l+d9rnAY=' 'sha256-HSGHqlRoKmHAGTAJ2Rq0piXX4CnEbOl1ArNd6ejp2TE=' ...;
64
- ```
@@ -1,104 +0,0 @@
1
- ## Named Appends
2
-
3
- Named Appends are blocks of code that can be reused and composed during requests. e.g. If a certain partial is rendered conditionally, and the csp needs to be adjusted for that partial, you can create a named append for that situation. The value returned by the block will be passed into `append_content_security_policy_directives`. The current request object is passed as an argument to the block for even more flexibility. Reusing a configuration name is not allowed and will throw an exception.
4
-
5
- ```ruby
6
- def show
7
- if include_widget?
8
- @widget = widget.render
9
- use_content_security_policy_named_append(:widget_partial)
10
- end
11
- end
12
-
13
-
14
- SecureHeaders::Configuration.named_append(:widget_partial) do |request|
15
- SecureHeaders.override_x_frame_options(request, "DENY")
16
- if request.controller_instance.current_user.in_test_bucket?
17
- { child_src: %w(beta.thirdpartyhost.com) }
18
- else
19
- { child_src: %w(thirdpartyhost.com) }
20
- end
21
- end
22
- ```
23
-
24
- You can use as many named appends as you would like per request, but be careful because order of inclusion matters. Consider the following:
25
-
26
- ```ruby
27
- SecureHeader::Configuration.default do |config|
28
- config.csp = { default_src: %w('self')}
29
- end
30
-
31
- SecureHeaders::Configuration.named_append(:A) do |request|
32
- { default_src: %w(myhost.com) }
33
- end
34
-
35
- SecureHeaders::Configuration.named_append(:B) do |request|
36
- { script_src: %w('unsafe-eval') }
37
- end
38
- ```
39
-
40
- The following code will produce different policies due to the way policies are normalized (e.g. providing a previously undefined directive that inherits from `default-src`, removing host source values when `*` is provided. Removing `'none'` when additional values are present, etc.):
41
-
42
- ```ruby
43
- def index
44
- use_content_security_policy_named_append(:A)
45
- use_content_security_policy_named_append(:B)
46
- # produces default-src 'self' myhost.com; script-src 'self' myhost.com 'unsafe-eval';
47
- end
48
-
49
- def show
50
- use_content_security_policy_named_append(:B)
51
- use_content_security_policy_named_append(:A)
52
- # produces default-src 'self' myhost.com; script-src 'self' 'unsafe-eval';
53
- end
54
- ```
55
-
56
-
57
- ## Named overrides
58
-
59
- Named overrides serve two purposes:
60
-
61
- * To be able to refer to a configuration by simple name.
62
- * By precomputing the headers for a named configuration, the headers generated once and reused over every request.
63
-
64
- To use a named override, drop a `SecureHeaders::Configuration.override` block **outside** of method definitions and then declare which named override you'd like to use. You can even override an override.
65
-
66
- ```ruby
67
- class ApplicationController < ActionController::Base
68
- SecureHeaders::Configuration.default do |config|
69
- config.csp = {
70
- default_src: %w('self'),
71
- script_src: %w(example.org)
72
- }
73
- end
74
-
75
- # override default configuration
76
- SecureHeaders::Configuration.override(:script_from_otherdomain_com) do |config|
77
- config.csp[:script_src] << "otherdomain.com"
78
- end
79
- end
80
-
81
- class MyController < ApplicationController
82
- def index
83
- # Produces default-src 'self'; script-src example.org otherdomain.com
84
- use_secure_headers_override(:script_from_otherdomain_com)
85
- end
86
-
87
- def show
88
- # Produces default-src 'self'; script-src example.org otherdomain.org evenanotherdomain.com
89
- use_secure_headers_override(:another_config)
90
- end
91
- end
92
- ```
93
-
94
- Reusing a configuration name is not allowed and will throw an exception.
95
-
96
- By default, a no-op configuration is provided. No headers will be set when this default override is used.
97
-
98
- ```ruby
99
- class MyController < ApplicationController
100
- def index
101
- SecureHeaders.opt_out_of_all_protection(request)
102
- end
103
- end
104
- ```
@@ -1,139 +0,0 @@
1
- ## Per-action configuration
2
-
3
- You can override the settings for a given action by producing a temporary override. Be aware that because of the dynamic nature of the value, the header values will be computed per request.
4
-
5
- ```ruby
6
- # Given a config of:
7
- ::SecureHeaders::Configuration.default do |config|
8
- config.csp = {
9
- default_src: %w('self'),
10
- script_src: %w('self')
11
- }
12
- end
13
-
14
- class MyController < ApplicationController
15
- def index
16
- # Append value to the source list, override 'none' values
17
- # Produces: default-src 'self'; script-src 'self' s3.amazonaws.com; object-src 'self' www.youtube.com
18
- append_content_security_policy_directives(script_src: %w(s3.amazonaws.com), object_src: %w('self' www.youtube.com))
19
-
20
- # Overrides the previously set source list, override 'none' values
21
- # Produces: default-src 'self'; script-src s3.amazonaws.com; object-src 'self'
22
- override_content_security_policy_directives(script_src: %w(s3.amazonaws.com), object_src: %w('self'))
23
-
24
- # Global settings default to "sameorigin"
25
- override_x_frame_options("DENY")
26
- end
27
- ```
28
-
29
- The following methods are available as controller instance methods. They are also available as class methods, but require you to pass in the `request` object.
30
- * `append_content_security_policy_directives(hash)`: appends each value to the corresponding CSP app-wide configuration.
31
- * `override_content_security_policy_directives(hash)`: merges the hash into the app-wide configuration, overwriting any previous config
32
- * `override_x_frame_options(value)`: sets the `X-Frame-Options header` to `value`
33
-
34
- ## Appending / overriding Content Security Policy
35
-
36
- When manipulating content security policy, there are a few things to consider. The default header value is `default-src https:` which corresponds to a default configuration of `{ default_src: %w(https:)}`.
37
-
38
- #### Append to the policy with a directive other than `default_src`
39
-
40
- The value of `default_src` is joined with the addition if the it is a [fetch directive](https://w3c.github.io/webappsec-csp/#directives-fetch). Note the `https:` is carried over from the `default-src` config. If you do not want this, use `override_content_security_policy_directives` instead. To illustrate:
41
-
42
- ```ruby
43
- ::SecureHeaders::Configuration.default do |config|
44
- config.csp = {
45
- default_src: %w('self')
46
- }
47
- end
48
- ```
49
-
50
- Code | Result
51
- ------------- | -------------
52
- `append_content_security_policy_directives(script_src: %w(mycdn.com))` | `default-src 'self'; script-src 'self' mycdn.com`
53
- `override_content_security_policy_directives(script_src: %w(mycdn.com))` | `default-src 'self'; script-src mycdn.com`
54
-
55
- #### Nonce
56
-
57
- You can use a view helper to automatically add nonces to script tags. Currently, using a nonce helper or calling `content_security_policy_nonce` will populate all configured CSP headers, including report-only and enforced policies.
58
-
59
- ```erb
60
- <%= nonced_javascript_tag do %>
61
- console.log("nonced!");
62
- <% end %>
63
-
64
- <%= nonced_style_tag do %>
65
- body {
66
- background-color: black;
67
- }
68
- <% end %>
69
-
70
- <%= nonced_javascript_include_tag "include.js" %>
71
-
72
- <%= nonced_javascript_pack_tag "pack.js" %>
73
-
74
- <%= nonced_stylesheet_link_tag "link.css" %>
75
-
76
- <%= nonced_stylesheet_pack_tag "pack.css" %>
77
- ```
78
-
79
- becomes:
80
-
81
- ```html
82
- <script nonce="/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI=">
83
- console.log("nonced!")
84
- </script>
85
- <style nonce="/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI=">
86
- body {
87
- background-color: black;
88
- }
89
- </style>
90
- ```
91
-
92
- ```
93
-
94
- Content-Security-Policy: ...
95
- script-src 'nonce-/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI=' ...;
96
- style-src 'nonce-/jRAxuLJsDXAxqhNBB7gg7h55KETtDQBXe4ZL+xIXwI=' ...;
97
- ```
98
-
99
- `script`/`style-nonce` can be used to whitelist inline content. To do this, call the `content_security_policy_script_nonce` or `content_security_policy_style_nonce` then set the nonce attributes on the various tags.
100
-
101
- ```erb
102
- <script nonce="<%= content_security_policy_script_nonce %>">
103
- console.log("whitelisted, will execute")
104
- </script>
105
-
106
- <script nonce="lol">
107
- console.log("won't execute, not whitelisted")
108
- </script>
109
-
110
- <script>
111
- console.log("won't execute, not whitelisted")
112
- </script>
113
- ```
114
-
115
- ## Clearing browser cache
116
-
117
- You can clear the browser cache after the logout request by using the following.
118
-
119
- ``` ruby
120
- class ApplicationController < ActionController::Base
121
- # Configuration override to send the Clear-Site-Data header.
122
- SecureHeaders::Configuration.override(:clear_browser_cache) do |config|
123
- config.clear_site_data = SecureHeaders::ClearSiteData::ALL_TYPES
124
- end
125
-
126
-
127
- # Clears the browser's cache for browsers supporting the Clear-Site-Data
128
- # header.
129
- #
130
- # Returns nothing.
131
- def clear_browser_cache
132
- SecureHeaders.use_secure_headers_override(request, :clear_browser_cache)
133
- end
134
- end
135
-
136
- class SessionsController < ApplicationController
137
- after_action :clear_browser_cache, only: :destroy
138
- end
139
- ```
data/docs/sinatra.md DELETED
@@ -1,25 +0,0 @@
1
- ## Sinatra
2
-
3
- Here's an example using SecureHeaders for Sinatra applications:
4
-
5
- ```ruby
6
- require 'rubygems'
7
- require 'sinatra'
8
- require 'haml'
9
- require 'secure_headers'
10
-
11
- use SecureHeaders::Middleware
12
-
13
- SecureHeaders::Configuration.default do |config|
14
- ...
15
- end
16
-
17
- class Donkey < Sinatra::Application
18
- set :root, APP_ROOT
19
-
20
- get '/' do
21
- SecureHeaders.override_x_frame_options(request, SecureHeaders::OPT_OUT)
22
- haml :index
23
- end
24
- end
25
- ```