GithubHelp home page GithubHelp logo

potomak / rack-ssl-enforcer Goto Github PK

View Code? Open in Web Editor NEW

This project forked from tobmatth/rack-ssl-enforcer

0.0 2.0 0.0 164 KB

A simple Rack middleware to enforce ssl connections

License: MIT License

Ruby 100.00%

rack-ssl-enforcer's Introduction

Rack::SslEnforcer Build Status

Rack::SslEnforcer is a simple Rack middleware to enforce SSL connections. As of Version 0.2.0, Rack::SslEnforcer marks Cookies as secure by default (HSTS must be set manually).

Tested against Ruby 1.8.7, 1.9.2, 1.9.3, ruby-head, REE and the latest versions of Rubinius & JRuby.

Installation

The simplest way to install Rack::SslEnforcer is to use Bundler.

Add Rack::SslEnforcer to your Gemfile:

 gem 'rack-ssl-enforcer'

Installing on Sinatra / Padrino application

In order for Rack::SslEnforcer to properly work it has to be at the top of the Rack Middleware.

Using enable :session will place Rack::Session::Cookie before Rack::Ssl::Enforcer and will prevent Rack::Ssl::Enforcer from marking cookies as secure.

To fix this issue do not use enable :sessions instead add the Rack::Session::Cookie middleware after Rack::Ssl::Enforcer.

Eg:

use Rack::SslEnforcer 
set :session_secret, 'asdfa2342923422f1adc05c837fa234230e3594b93824b00e930ab0fb94b'

#Enable sinatra sessions
use Rack::Session::Cookie, :key => '_rack_session',
                           :path => '/',
                           :expire_after => 2592000, # In seconds
                           :secret => session_secret

Basic Usage

If you don't use Bundler, be sure to require Rack::SslEnforcer manually before actually using the middleware:

 require 'rack/ssl-enforcer'
 use Rack::SslEnforcer

To use Rack::SslEnforcer in your Rails application, add the following line to your application config file (config/application.rb for Rails 3, config/environment.rb for Rails 2):

config.middleware.use Rack::SslEnforcer

If all you want is SSL for your whole application, you are done! Otherwise, you can specify some options described below.

Options

Host constraints

You can enforce SSL connections only for certain hosts with :only_hosts, or prevent certain hosts from being forced to SSL with :except_hosts. Constraints can be a String, a Regex or an array of String or Regex (possibly mixed), as shown in the following examples:

config.middleware.use Rack::SslEnforcer, :only_hosts => 'api.example.com'
# Please note that, for instance, both http://help.example.com/demo and https://help.example.com/demo would be accessible here

config.middleware.use Rack::SslEnforcer, :except_hosts => /[help|blog]\.example\.com$/

config.middleware.use Rack::SslEnforcer, :only_hosts => [/[secure|admin]\.example\.org$/, 'api.example.com']

Path constraints

You can enforce SSL connections only for certain paths with :only, prevent certain paths from being forced to SSL with :except, or - if you don't care how certain paths are accessed - ignore them with :ignore. Constraints can be a String, a Regex or an array of String or Regex (possibly mixed), as shown in the following examples:

config.middleware.use Rack::SslEnforcer, :only => '/login'
# Please note that, for instance, both http://example.com/demo and https://example.com/demo would be accessible here

config.middleware.use Rack::SslEnforcer, :only => %r{^/admin/}

config.middleware.use Rack::SslEnforcer, :except => ['/demo', %r{^/public/}]

config.middleware.use Rack::SslEnforcer, :ignore => '/assets'

Method constraints

You can enforce SSL connections only for certain HTTP methods with :only_methods, or prevent certain HTTP methods from being forced to SSL with :except_methods. Constraints can be a String or an array of String, as shown in the following examples:

# constraint as a String
config.middleware.use Rack::SslEnforcer, :only_methods => 'POST'
# Please note that, for instance, GET requests would be accessible via SSL and non-SSL connection here

config.middleware.use Rack::SslEnforcer, :except_methods => ['GET', 'HEAD']

Note: The :hosts constraint takes precedence over the :path constraint. Please see the tests for examples.

Force-redirection to non-SSL connection if constraint is not matched

Use the :strict option to force non-SSL connection for all requests not matching the constraints you set. Examples:

config.middleware.use Rack::SslEnforcer, :only => ["/login", /\.xml$/], :strict => true
# https://example.com/demo would be redirected to http://example.com/demo

config.middleware.use Rack::SslEnforcer, :except_hosts => 'demo.example.com', :strict => true
# https://demo.example.com would be redirected to http://demo.example.com

Automatic method constraints

In the case where you have matching URLs with different HTTP methods – for instance Rails RESTful routes: GET /users, POST /users, GET /user/:id and PUT /user/:id – you may need to force POST and PUT requests to SSL connection but redirect to non-SSL connection on GET.

config.middleware.use Rack::SslEnforcer, :only => [%r{^/users/}], :mixed => true

The above will allow you to POST/PUT from the secure/non-secure URLs keeping the original schema.

HTTP Strict Transport Security (HSTS)

To set HSTS expiry and subdomain inclusion (defaults respectively to one year and true).

config.middleware.use Rack::SslEnforcer, :hsts => { :expires => 500, :subdomains => false }
config.middleware.use Rack::SslEnforcer, :hsts => true # equivalent to { :expires => 31536000, :subdomains => true }

Please note that the strict option disables HSTS.

Redirect to specific URL (e.g. if you're using a proxy)

You might need the :redirect_to option if the requested URL can't be determined.

config.middleware.use Rack::SslEnforcer, :redirect_to => 'https://example.org'

Custom HTTP port

If you're using a different port than the default (80) for HTTP, you can specify it with the :http_port option:

config.middleware.use Rack::SslEnforcer, :http_port => 8080

Custom HTTPS port

If you're using a different port than the default (443) for HTTPS, you can specify it with the :https_port option:

config.middleware.use Rack::SslEnforcer, :https_port => 444

Secure cookies disabling

Finally you might want to share a cookie based session between HTTP and HTTPS. This is not possible by default with Rack::SslEnforcer for security reasons.

Nevertheless, you can set the :force_secure_cookies option to false in order to be able to share a cookie based session between HTTP and HTTPS:

config.middleware.use Rack::SslEnforcer, :only => "/login", :force_secure_cookies => false

But be aware that if you do so, you have to make sure that the content of you cookie is encoded. This can be done using a coder with Rack::Session::Cookie.

Deployment

If you run your application behind a proxy (e.g. Nginx) you may need to do some configuration on that side. If you don't you may experience an infinite redirect loop.

The reason this happens is that Rack::SslEnforcer can't detect if you are running SSL or not. The solution is to have your front-end server send extra headers for Rack::SslEnforcer to identify the request protocol.

Nginx

In the location block for your app's SSL configuration, include the following proxy header configuration:

proxy_set_header X-Forwarded-Proto https;

Passenger

Or, if you're using mod_rails/passenger (which will ignore the proxy_xxx directives):

passenger_set_cgi_param HTTP_X_FORWARDED_PROTO https;

If you're sharing a single server block for http AND https access you can add:

passenger_set_cgi_param HTTP_X_FORWARDED_PROTO $scheme;

This makes sure that Rack::SslEnforcer knows it's being accessed over SSL. Just restart Nginx for these changes to take effect.

TODO

  • Cleanup tests

Contributors

Credits

Flagging cookies as secure functionality and HSTS support is greatly inspired by Joshua Peek's Rack::SSL.

Note on Patches / Pull Requests

  • Fork the project.
  • Code your feature addition or bug fix.
  • Add tests for it. This is important so we don't break it in a future version unintentionally.
  • Commit, do not mess with Rakefile or version number. If you want to have your own version, that's fine but bump version in a commit by itself so we can ignore it when merging.
  • Send a pull request. Bonus points for topic branches.

Copyright

Copyright (c) 2010-2012 Tobias Matthies. See LICENSE for details.

rack-ssl-enforcer's People

Contributors

alan avatar ariejan avatar danmayer avatar juno avatar krekoten avatar ktopping avatar kylecrum avatar lardawge avatar natacado avatar pda avatar rymai avatar thibaudgg avatar tobmatth avatar zanker avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.