MIT License

项目介绍

github/secure_headers 是一个托管在 GitHub 上的开源项目,主要使用 Ruby 编写,采用 MIT License 许可证,目前获得 3.2k 个 Star、252 次 Fork。

仓库全名
github/secure_headers
开源许可证
MIT License
Star 数
3.2k
Fork 数
252
未关闭 Issue
13

README 摘要

main branch represents 7.x line. See the upgrading to 4.x doc, upgrading to 5.x doc, upgrading to 6.x doc or upgrading to 7.x doc for instructions on how to upgrade. Bug fixes should go in the 6.x branch for now. The gem will automatically apply several headers that are related to security. This includes: Content Security Policy (CSP) - Helps detect/prevent XSS, mixed-content, and other classes of attack. CSP 2…

完整内容见 GitHub 原始 README 或本页 。

常见问题

secure_headers 用什么语言开发?

主要使用 Ruby 编写,采用 MIT License 许可证,目前有 3.2k 个 Star。

secure_headers 可以免费商用吗?

仓库采用 MIT License 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 secure_headers 的源码?

可以直接克隆仓库:git clone https://github.com/github/secure_headers.git,默认分支为 main;安装与运行步骤见仓库 README。

secure_headers 最近还在维护吗?

仓库最近一次更新为 2 天前,当前有 13 个未关闭 Issue;Star 数为 3.2k,可作为社区活跃度的参考。

README

Secure Headers Build + Test

main branch represents 7.x line. See the upgrading to 4.x doc, upgrading to 5.x doc, upgrading to 6.x doc or upgrading to 7.x doc for instructions on how to upgrade. Bug fixes should go in the 6.x branch for now.

The gem will automatically apply several headers that are related to security. This includes:

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.

secure_headers is a library with a global config, per request overrides, and rack middleware that enables you customize your application settings.

Documentation

Configuration

If you do not supply a default configuration, exceptions will be raised. If you would like to use a default configuration (which is fairly locked down), just call SecureHeaders::Configuration.default without any arguments or block.

All nil values will fallback to their default values. SecureHeaders::OPT_OUT will disable the header entirely.

Word of caution: The following is not a default configuration per se. It serves as a sample implementation of the configuration. You should read more about these headers and determine what is appropriate for your requirements.

SecureHeaders::Configuration.default do |config|
  config.cookies = {
    secure: true, # mark all cookies as "Secure"
    httponly: true, # mark all cookies as "HttpOnly"
    samesite: {
      lax: true # mark all cookies as SameSite=lax
    }
  }
  # Add "; preload" and submit the site to hstspreload.org for best protection.
  config.hsts = "max-age=#{1.week.to_i}"
  config.x_frame_options = "DENY"
  config.x_content_type_options = "nosniff"
  config.x_xss_protection = "1; mode=block"
  config.x_download_options = "noopen"
  config.x_permitted_cross_domain_policies = "none"
  config.referrer_policy = %w(origin-when-cross-origin strict-origin-when-cross-origin)
  config.csp = {
    # "meta" values. these will shape the header, but the values are not included in the header.
    preserve_schemes: true, # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
    disable_nonce_backwards_compatibility: true, # default: false. If false, `unsafe-inline` will be added automatically when using nonces. If true, it won't. See #403 for why you'd want this.

    # directive values: these values will directly translate into source directives
    default_src: %w('none'),
    base_uri: %w('self'),
    child_src: %w('self'), # if child-src isn't supported, the value for frame-src will be set.
    connect_src: %w(wss:),
    font_src: %w('self' data:),
    form_action: %w('self' github.com),
    frame_ancestors: %w('none'),
    img_src: %w(mycdn.com data:),
    manifest_src: %w('self'),
    media_src: %w(utoob.com),
    object_src: %w('self'),
    sandbox: true, # true and [] will set a maximally restrictive setting
    plugin_types: %w(application/x-shockwave-flash),
    script_src: %w('self'),
    script_src_elem: %w('self'),
    script_src_attr: %w('self'),
    style_src: %w('unsafe-inline'),
    style_src_elem: %w('unsafe-inline'),
    style_src_attr: %w('unsafe-inline'),
    worker_src: %w('self'),
    upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
    report_uri: %w(https://report-uri.io/example-csp)
  }
  # This is available only from 3.5.0; use the `report_only: true` setting for 3.4.1 and below.
  config.csp_report_only = config.csp.merge({
    img_src: %w(somewhereelse.com),
    report_uri: %w(https://report-uri.io/example-csp-report-only)
  })

  # Optional: Use the modern report-to directive (with Reporting-Endpoints header)
  config.csp = config.csp.merge({
    report_to: "csp-endpoint"
  })

  # When using report-to, configure the reporting endpoints header
  config.reporting_endpoints = {
    "csp-endpoint": "https://report-uri.io/example-csp",
    "csp-report-only": "https://report-uri.io/example-csp-report-only"
  }
end

CSP Reporting

SecureHeaders supports both the legacy report-uri and the modern report-to directives for CSP violation reporting:

report-uri (Legacy)

The report-uri directive sends violations to a URL endpoint. It’s widely supported but limited to POST requests with JSON payloads.

config.csp = {
  default_src: %w('self'),
  report_uri: %w(https://example.com/csp-report)
}
report-to (Modern)

The report-to directive specifies a named reporting endpoint defined in the Reporting-Endpoints header. This enables more flexible reporting through the HTTP Reporting API standard.

config.csp = {
  default_src: %w('self'),
  report_to: "csp-endpoint"
}

config.reporting_endpoints = {
  "csp-endpoint": "https://example.com/reports"
}

Recommendation: Use both report-uri and report-to for maximum compatibility while transitioning to the modern approach.

Deprecated Configuration Values

Default values

All headers except for PublicKeyPins and ClearSiteData have a default value. The default set of headers is:

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'
strict-transport-security: max-age=631138519
x-content-type-options: nosniff
x-download-options: noopen
x-frame-options: sameorigin
x-permitted-cross-domain-policies: none
x-xss-protection: 0

API configurations

Which headers you decide to use for API responses is entirely a personal choice. Things like X-Frame-Options seem to have no place in an API response and would be wasting bytes. While this is true, browsers can do funky things with non-html responses. At the minimum, we suggest CSP:

SecureHeaders::Configuration.override(:api) do |config|
  config.csp = { default_src: 'none' }
  config.hsts = SecureHeaders::OPT_OUT
  config.x_frame_options = SecureHeaders::OPT_OUT
  config.x_content_type_options = SecureHeaders::OPT_OUT
  config.x_xss_protection = SecureHeaders::OPT_OUT
  config.x_permitted_cross_domain_policies = SecureHeaders::OPT_OUT
end

However, I would consider these headers anyways depending on your load and bandwidth requirements.

Disabling secure_headers

If you want to disable secure_headers entirely (e.g., for specific environments or deployment scenarios), you can use Configuration.disable!:

if ENV["ENABLE_STRICT_HEADERS"]
  SecureHeaders::Configuration.default do |config|
    # your configuration here
  end
else
  SecureHeaders::Configuration.disable!
end

Important: This configuration must be set during application startup (e.g., in an initializer). Once you call either Configuration.default or Configuration.disable!, the choice cannot be changed at runtime. Attempting to call disable! after default (or vice versa) will raise an AlreadyConfiguredError.

When disabled, no security headers will be set by the gem. This is useful when:

  • You’re gradually rolling out secure_headers across different customers or deployments
  • You need to migrate existing custom headers to secure_headers
  • You want environment-specific control over security headers

Note: When disable! is used, you don’t need to configure a default configuration. The gem will not raise a NotYetConfiguredError.

Acknowledgements

This project originated within the Security team at Twitter. An archived fork from the point of transition is here: https://github.com/twitter-archive/secure_headers.

Contributors include:

  • Neil Matatall @oreoshake
  • Chris Aniszczyk
  • Artur Dryomov
  • Bjørn Mæland
  • Arthur Chiu
  • Jonathan Viney
  • Jeffrey Horn
  • David Collazo
  • Brendon Murphy
  • William Makley
  • Reed Loden
  • Noah Kantrowitz
  • Wyatt Anderson
  • Salimane Adjao Moustapha
  • Francois Chagnon
  • Jeff Hodges
  • Ian Melven
  • Darío Javier Cravero
  • Logan Hasson
  • Raul E Rangel
  • Steve Agalloco
  • Nate Collings
  • Josh Kalderimis
  • Alex Kwiatkowski
  • Julich Mera
  • Jesse Storimer
  • Tom Daniels
  • Kolja Dummann
  • Jean-Philippe Doyle
  • Blake Hitchcock
  • vanderhoorn
  • orthographic-pedant
  • Narsimham Chelluri

If you’ve made a contribution and see your name missing from the list, make a PR and add it!

Similar libraries

评论

暂无评论