Mastering Cross-Origin Communication with Rack CORS in Rails
Posted at 24-September-2023 / Written by Rohit Bhatt
30-sec summary
Web browsers have a set of rules in place to prevent web pages from accessing resources on different origins without permission. This policy, known as the same-origin policy, ensures that a web page can only access resources that have the same origin as the page itself. However, there are scenarios where web applications need to communicate with other origins for legitimate purposes, such as fetching data from an API or loading web fonts. In such cases, cross-origin resource sharing (CORS) comes into play. In this article, we will explore how to implement CORS in a Rails application and understand its significance.
Browser Cross-Origin Policy
The browser cross-origin policy serves the dual purpose of protecting web pages from malicious attacks and restricting the functionality of web applications. The policy safeguards against cross-site request forgery (CSRF), cross-site script inclusion (XSSI), and speculative side-channel attacks like Spectre, which can compromise the security, privacy, and integrity of web pages and their users. However, this policy also poses limitations on web applications that require legitimate cross-origin communication. To enable such scenarios, browsers support mechanisms like CORS, CORP, COEP, and COOP.
- 1.Cross-Origin Resource Sharing (CORS): This mechanism, based on HTTP headers, allows servers to indicate which origins are permitted to access their resources and under what conditions. CORS may involve sending preflight requests for certain cross-origin requests to check the server’s CORS policy before making the actual request.
- 2.Cross-Origin Resource Policy (CORP): CORP is an additional layer of protection that allows servers to opt-in to defense against specific cross-origin requests from other origins, including those issued with <script> and <img> elements. CORP acts as a safeguard beyond the default same-origin policy.
- 3.Cross-Origin Embedder Policy (COEP): This HTTP-header based mechanism allows a document to enforce same-origin or CORP header requirements on its subresources. COEP enables the use of features that require cross-origin isolation, such as SharedArrayBuffer or performance.measureUserAgentSpecificMemory().
- 4.Cross-Origin Opener Policy (COOP): COOP provides control over how a document can be accessed by other documents in a browsing context group, such as a tab or window. By restricting access to the document’s global object, COOP mitigates certain types of cross-site leaks.
Rack CORS in Rails
Rack CORS is a middleware that enables Cross-Origin Resource Sharing (CORS) for Rack-compatible web applications, including Rails. Rack serves as the web server interface for Rails, offering a modular approach for web applications to interact with web servers using a single method call. With Rack CORS, developers can easily configure CORS for their Rails API, allowing front-end applications to access API data without encountering CORS errors or security issues.
Advantages of Using Rack CORS in Rails
By incorporating Rack CORS as middleware in Rails, developers can benefit from the following advantages:
- 1.Seamless Integration: As Rack is the interface for Rails, integrating Rack CORS becomes straightforward. Rack middleware allows modification of requests or responses before or after reaching the application, making it an ideal solution for handling CORS-related tasks.
- 2.Customization: Rack CORS provides flexibility to configure which origins, methods, headers, and resources are allowed or exposed in CORS requests and responses. Developers can tailor the CORS policy according to their specific requirements.
Implementing Rack CORS in Rails
Install the rack-cors gem by executing either gem install rack-cors or by adding gem ‘rack-cors’ to your Gemfile and running bundle install.
- 1.Install the rack-cors gem by executing either gem install rack-cors or by adding gem ‘rack-cors’ to your Gemfile and running bundle install.
- 2.In the config/initializers/cors.rb file, insert the following code to include the Rack CORS middleware and define your CORS policy:
1Rails.application.config.middleware.insert_before 0, Rack::Cors do
2 allow do
3 # Specify which origins are allowed to make CORS requests
4 origins 'localhost:3000', 'example.com'
5
6 # Specify which resources are allowed and which methods and headers are supported
7 resource '/api/*',
8 headers: :any,
9 methods: [:get, :post, :put, :patch, :delete, :options, :head],
10 expose: ['X-Total-Count', 'Link'], # Optional: specify which response headers are exposed to the browser
11 max_age: 86400 # Optional: specify how long the preflight request cache should last
12 end
13 end
Restart your Rails server for the changes to take effect
By adjusting the values of the origins, resource, headers, methods, expose, and max_age options, you can customize the CORS policy to meet your application’s specific requirements. Multiple allow blocks can be added to define different policies for different origins or resources.
Conclusion
The browser cross-origin policy serves as a crucial security measure, preventing unauthorized access to web resources. However, it can hinder legitimate cross-origin communication needed by web applications. By utilizing Rack CORS as middleware in a Rails application, developers can easily enable and customize CORS, ensuring seamless interaction between front-end apps and back-end APIs. Rack CORS empowers developers to define their CORS policies, allowing controlled access to resources and preventing CORS-related issues. Implementing Rack CORS in Rails helps developers strike a balance between security and functionality, providing a robust foundation for building web applications with effective cross-origin communication capabilities.