Skip to content

raymondboswel/secure_headers

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SecureHeaders

This Plug will automatically apply several security headers to the Plug.Conn response. By design SecureHeaders will attempt to apply the most strict security policy. Although, security headers are configurable and are validated to avoid misconfiguration.

The supported security headers include:

Installation

SecureHeaders is available in Hex (https://hex.pm/packages/secure_headers) and can be installed as:

  1. Add secure_headers to your list of dependencies in mix.exs:

    def deps do [{:secure_headers, "~> 0.0.1"}] end

  2. Ensure secure_headers is started before your application:

    def application do [applications: [:secure_headers]] end

  3. Add the plug to your application, e.g., to a pipeline in a Phoenix router.

  • Don't forget to run mix deps.get *

SecureHeaders by design defaults to a strict security policy. If no opts are supplied it uses the following secure configuration:

config secure_headers:, SecureHeaders, 
  config: [
      content_security_policy: "default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';", 
      http_public_key_pins: "", 
      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: "1; mode=block"
  ]
]
defmodule SecurePhoenixApp.SecureRouter do
  use SecurePhoenixApp.Web, :router
  
  pipeline :browser do
    plug :accepts, ["html", "text"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug SecureHeaders
  end

  scope "/", HelloPhoenix do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
  end
end    
defmodule SecurePhoenixApp.SecureController do
  use SecurePhoenixApp.Web, :controller
  alias Plug.Conn.Status

  def index(conn, _params) do
    conn
    |> put_status(Status.code :ok)
    |> text """
    SecureHeaders secure configuration:
    
    Content Security Policy (CSP):         #{conn.assigns[:content_security_policy]}
    HTTP Strict Transport Security (HSTS): #{conn.assigns[:strict_transport_security]}
    X-Content-Type-Options:                #{conn.assigns[:x_content_type_options]}
    X-Download-Options:                    #{conn.assigns[:x_download_options]}
    X-Frame-Options (XFO):                 #{conn.assigns[:x_frame_options]}
    X-Permitted-Cross-Domain-Policies:     #{conn.assigns[:x_permitted_cross_domain_policies]}  
    X-XSS-Protection:                      #{conn.assigns[:x_xss_protection]}
    Public Key Pinning:                    #{conn.assigns[:http_public_key_pins]}     

    """
    end
end

Configuration values can be overridden in the application environment. By default they will be merged with the default secure header configuration.

Order of merge resolution

First - config provided in-line to the plug

    plug SecureHeaders secure_headers: [config: [x_xss_protection: "1; mode=block"]]

Second - config in Application environment

# filename: dev.exs

use Mix.Config

config secure_headers:, SecureHeaders, 
    config: [
      content_security_policy: "default-src 'self';" , 
      strict_transport_security: "max-age=631138519", 
      x_permitted_cross_domain_policies: "none", 
      x_xss_protection: "0"
    ]

Third - default secure config

You can disable merging application environment configuration with the default secure configuration by providing the following option [merge_config: false] to SecureHeaders:

defmodule SecurePhoenixApp.SecureRouter do
  use SecurePhoenixApp.Web, :router
  
  pipeline :browser do
    plug :accepts, ["html", "text"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug SecureHeaders secure_headers: [merge_config: false]
  end

  scope "/", HelloPhoenix do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
  end
end    

TODOs

  • Implement nonce for Content Security Policies
  • Write tests for Content Security Policies
  • Finish Documentation (README and moddocs)

About

HTTP security headers for Phoenix/Plug

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Elixir 100.0%