Secure AJAX-style actions for Rails applications
Ruby JavaScript
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


SecureEscrow proxies requests made to your application on a secure domain, stores the response, redirects the user to resources on an insecure domain, and serves the proxied response. It uses your preferred key-value store to hold responses between requests.

The Goals

This tool was created for two purposes:

  • Secure authentication from an insecure page without a full-page refresh
  • Secure authentication from a 3rd party-domain

The Solution

Your Rails application needs very little modification in order to support these secure actions.

Say you have a #signin ajax action that is currently insecure. Secure Escrow first helps you generate the same form with its action pointing to a secure domain. Also, instead of submitting the form via XHR, an iframe is dynamically-created and the form's target is set to that iframe. When the submission is received by the Secure Escrow middleware, the request is forwarded along to your Rails application. The response from Rails is then cached and an alternate response is delivered to the client. The client is redirected to GET action on the insecure domain. This action is served by the Secure Escrow middleware, and contains the cached response from the Rails application, leaving your app totally unaware that a redirection has occurred. The response is then parsed and passed back to your registered AJAX handler.


Add the following line to your Gemfile.

gem 'secure_escrow'

Update your application's bundle.

$ bundle install


SecureEscrow has 5 integration points with a Rails application

  • Middleware surrounding your application
  • Domain information in application configuration
  • Routes declared as escrowed
  • JavaScript delivered via the asset pipeline
  • Forms generated by views

Note: Currently, SecureEscrow requires jQuery for capturing form submission events and creating elements in the DOM.

Install as Middleware

Add the SecureEscrow::Middleware around your Rails application. It must be configured with both a Rack endpoint to call, and a Rails app instance to retrieve routes and configuration information from. In this example, the Awesome::Application.config.redis value is available after the environment file has been run.

Example config/initializers/secure_escrow.rb:

  store: Awesome::Application.config.redis

Configure Domain Information

Ordinarily Rails simply uses the client-supplied request hostname to generate URLs. SecureEscrow needs to redirect to a domain which may not be the same as the incoming request. Configuration is supplied on the Rails application instance, and may differ for various environments. For example, in development.rb you might have the following config.

# = SecureEscrow config =
config.secure_escrow = {
  secure_domain_name:       '',
  secure_domain_protocol:   'http',
  secure_domain_port:       3000,
  insecure_domain_name:     'www.insecure-awesome.devlocal',
  insecure_domain_protocol: 'http',
  insecure_domain_port:     3000,

Declare Escrowed Routes

In your Rails application's routes.rb file you can declare escrowed routes. Escrow only applies to POST actions. In the following example, I show replacing a post route with an escrow route.


get    'signin' => 'sessions#new',      as: :new_user_session
post   'signin' => 'sessions#create',   as: :user_session
get    'signout'=> 'sessions#destroy',  as: :destroy_user_session


get    'signin' => 'sessions#new',      as: :new_user_session
escrow 'signin' => 'sessions#create',   as: :user_session
get    'signout'=> 'sessions#destroy',  as: :destroy_user_session

Alternatively, SecureEscrow can be configured to escrow any POST action without explicitly declaring it within the application. Just provide allow_non_escrow_routes: true to the initial SecureEscrow configuration.

Deliver JavaScript assets

SecureEscrow integrates in the Rails asset pipeline. Just add the following to your application.js.

// SecureEscrow
// ======================
//= require secure_escrow

Generate forms that submit to the escrow

View helpers are provided to generate forms that submit to the escrow.

Replace form_for with escrow_form_for and form_tag with escrow_form_tag.