Skip to content

Instantly share code, notes, and snippets.

Last active Aug 13, 2018
What would you like to do?
GSoC 2018 Final Report

Google Summer of Code

Google Summer of Code 2018

Refactor Rails' Cookie Implementation and Improve Signing with Expiry and Purpose continuation & Server Timing Middleware

Ruby on Rails Project GSoC'17 continuation & Server Timing Middleware
Organization Ruby on Rails
GSoC link
Student Assain K C

Project Goal

The main goals of the project are:

  • Improve the security of the cookie system in Rails by introducing purpose metadata.
  • Port SignedGlobalId to use ActiveSupport::MessageVerifier to handle metadata.
  • Introduce a new Rack Middleware called Server Timing Middleware.

Purpose Metadata For Signed/Encrypted Cookies

Attackers could copy the value of one cookie and plug it in as the value of another cookie.

For example,

cookies.signed[:user_id] = 50
cookies.signed[:discount_percentage] = 10

In the above example, an attacker could copy the value of cookies[:user_id] and plug it in as the value of cookies[:discount _percentage] to get himself a 50% discount or vice versa.

To prevent such attacks, the name of the cookie is tacked-on to the cookie value using the purpose metadata added to Activesupport::MessageEncryptor and Activesupport:: MessageVerifier. Also, it ensures that the cookie is used only for it's intended use.

With this Pull Request: rails/rails#32937 merged in the Rails repository:

Rails can now thwart attacks that attempt to copy signed/encrypted value of a cookie and use it as the value of another cookie.

It does so by stashing the cookie-name in the purpose field which is then signed/encrypted along with the cookie value. Then, on a server-side read, we verify the cookie-names and discard any attacked cookies.

Enable action_dispatch.use_cookies_with_metadata to use this feature, which writes cookies with the new purpose and expiry metadata embedded, while taking care that old cookies are still honored and meshes well with the new changes.

Port SignedGlobalId to use ActiveSupport::MessageVerifier to handle metadata

Port SignedGlobalID to use ActiveSupport::MessageVerifier's metadata supported added during Google Summer of Code 2017. While fixing up the old tests, adding new one's and how it orchestrates with other versions of the gemfiles.

Server Timing Middleware

In pursuit of optimizing application performance, developers currently dig through log files, use external tools, and other methods to identify bottlenecks in their applications. As a solution, we're planning to introduce a new rack middleware called The Server Timing Middleware.

The Server Timing Middleware communicates performance metrics to the browser to help developers zoom-in on performance bottlenecks and their root cause.

We had decided upon how the header field should look like, besides Rails already computes a lot useful metrics. Therefore, the next step is to get these metrics as part of the Server-Timing Header using ActiveSupport::Instrumentation.

The Story So Far

Here's the breakdown of our major milestones:

Purpose Metadata For Signed/Encrypted Cookies

  • Cookies Test App to understand how different versions mesh together
  • #32937 Add purpose metadata to Cookies
  • #33605 Changelog and improved tests for purpose metadata added to cookies


  • #107 Port SignedGlobalID to use ActiveSupport::MessageVerifier's metadata support.

Server Timing Middleware

  • 32859 Fix Documentation in ActiveSupport Instrumentation Guide

**** The checked milestones link to the corresponding merged Pull Requests which contain further information, while others are work in progress and still being polished.

In short, we've refreshed and bolstered Rails with:

Improved signed/encrypted cookies capable of thwarting copy-paste attacks, i.e. cookie values can't be copy pasted and repurposed.

Future Work

The next big leap in our mission to improve Rails is to continue working on the new Server Timing Rack Middleware and integrate it with Rails. And also to complete the ongoing clean up of GlobalID's tests and configurations so that it's up-to-date.


First and foremost, I'd like to thank my wonderful mentors Kapser Timm Hansen and Guillermo Iguaran for the constant support and guidance throughout the project. Thanks a billion, Kasper, for enlightening me with your prudent wisdom and teaching me to stand on my own feet.

Special thanks to all the awesome people in the Rails Team for giving us your precious time and enlightening us with your expertise.

Last but not least, I'd like to thank Google for blessing us with this fantastic learning opportunity through The Google Summer of Code program, which has helped me open the doors and explore the amazing world of open source software with Ruby on Rails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment