Uncontrolled external site redirect - Ruby

Uncontrolled external site redirect - Ruby

Need

Controlled and secure external site redirects

Context

  • Requirement of Ruby 2.0 or higher for executing the code
  • Usage of Rails for building web applications with Ruby

Description

Non compliant code

        def redirect
  redirect_to params[:url]
end
        
        

In the above code, the application is redirecting to a URL based on the params[:url] value. This value is directly taken from the parameters that are sent to the server in a request, without any validation or sanitation.

This is a security vulnerability known as "Uncontrolled External Site Redirect". An attacker could manipulate the :url parameter to point to an external site. This could be used in phishing attacks to trick users into visiting malicious sites.

For example, an attacker could send a link to a user that looks like it goes to the application, but the :url parameter is set to http://malicious-site.com. When the user clicks on the link, they would be redirected to the malicious site.

This is a serious security flaw that can lead to data theft, as users might enter their credentials into the malicious site, thinking they are logging into the legitimate application.

Steps

  • Validate the input: Before redirecting, validate the URL to ensure it is a trusted and valid URL. Use a whitelist approach to only allow specific URLs.
  • Sanitize the input: Use a URL sanitizer to remove any potentially malicious characters or scripts from the URL.
  • Implement a redirect whitelist: Maintain a list of trusted URLs that the application is allowed to redirect to. Only redirect to URLs in this whitelist.
  • Implement a redirect blacklist: Maintain a list of known malicious URLs that the application should never redirect to. Check the input URL against this blacklist before redirecting.
  • Use a safe redirect method: Instead of directly using the 'redirect_to' method, use a safer alternative provided by the framework that ensures the redirect is controlled and secure.
  • Implement a redirect validation mechanism: Add a validation step before performing the redirect to verify that the redirect is intended and authorized. This can include additional user authentication or authorization checks.
  • Log and monitor redirects: Implement logging and monitoring mechanisms to track and detect any suspicious or unauthorized redirects.
  • Regularly update and patch dependencies: Keep the Ruby on Rails framework and any relevant libraries up to date to ensure that any security vulnerabilities are addressed.

Compliant code

        # List of trusted URLs
TRUSTED_URLS = ['http://trusted1.com', 'http://trusted2.com']

def redirect
  url = params[:url]
  
  # Validate and sanitize the URL
  if url.present? && url_valid?(url)
    # Check against trusted URLs
    if TRUSTED_URLS.include?(url)
      redirect_to url
    else
      # Log and handle untrusted URL
      Rails.logger.warn("Untrusted redirect attempt to #{url}")
      redirect_to root_path
    end
  else
    # Log and handle invalid URL
    Rails.logger.warn("Invalid redirect attempt to #{url}")
    redirect_to root_path
  end
end

def url_valid?(url)
  uri = URI.parse(url)
  uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
rescue URI::InvalidURIError
  false
end
        
        

The updated code includes a list of trusted URLs that the application is allowed to redirect to. Before redirecting, the code checks if the URL is present and valid. The url_valid? method uses Ruby's URI library to parse the URL and checks if it is a kind of HTTP or HTTPS URL. If the URL is invalid, an URI::InvalidURIError is raised and caught, and the method returns false.

If the URL is valid, the code checks if it is included in the list of trusted URLs. If it is, the application redirects to the URL. If it is not, the application logs a warning about the untrusted redirect attempt and redirects to the root path.

If the URL is not valid, the application logs a warning about the invalid redirect attempt and also redirects to the root path. This ensures that the application only redirects to trusted and valid URLs, preventing uncontrolled external site redirects.

References