Missing subresource integrity check - Ruby
Need
Enforcement of subresource integrity checks
Context
- Usage of Ruby for building dynamic and object-oriented applications
- Usage of Ruby on Rails for web application development
Description
Insecure Code Example
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def index
@external_js = 'https://third-party.com/external.js'
end
end
# app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>SampleApp</title>
<%= javascript_include_tag @external_js %>
</head>
<body>
<%= yield %>
</body>
</html>
In the above code, the `index` method in `ApplicationController` is setting `@external_js` to be the URL of a JavaScript file hosted on a third-party server. This URL is then being passed to the `javascript_include_tag` helper in the application's layout file, which generates a script tag to load the JavaScript file. The vulnerability here is that there is no subresource integrity check being performed on this external JavaScript file. This means that if the third-party server is compromised, or if the file is modified in transit, the application will still execute the JavaScript file without any warnings. This could lead to malicious code being executed in the context of the application, potentially leading to a variety of attacks such as Cross-Site Scripting (XSS).
Steps
- Implement subresource integrity (SRI) checks for external resources.
- Generate the integrity hash for the external resource.
- Update the view to include the integrity attribute for the external resource.
- Verify that the integrity check passes for the external resource.
Secure Code Example
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def index
@external_js = 'https://third-party.com/external.js'
@external_js_integrity = 'sha384-XXXX' # Replace 'sha384-XXXX' with the actual hash
end
end
# app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>SampleApp</title>
<%= javascript_include_tag @external_js, integrity: @external_js_integrity, crossorigin: 'anonymous' %>
</head>
<body>
<%= yield %>
</body>
</html>
The above code fixes the vulnerability by implementing Subresource Integrity (SRI) checks for the external JavaScript file. In the ApplicationController, along with the URL of the external JavaScript file, we also define its integrity hash. This hash is a base64-encoded cryptographic hash of the resource's content. In the application layout file, we include the integrity hash when including the JavaScript file. The `integrity` attribute in the `javascript_include_tag` helper method is used to specify the hash. The `crossorigin` attribute is also added with the value 'anonymous' to allow CORS. When the browser loads the external JavaScript file, it computes the hash of the received data and compares it with the provided hash. If they match, the browser understands that the file was not tampered with during the transmission and executes it. If they don't match, the browser refuses to execute the file, thus preventing any potential malicious code execution. Remember to replace 'sha384-XXXX' with the actual hash of the external JavaScript file. You can generate the hash using online SRI hash generators or command-line tools like openssl.
References
Last updated
2023/09/18