Sensitive information sent via URL parameters - Session - Ruby

Sensitive information sent via URL parameters - Session - Ruby

Need

Secure transmission of sensitive information in session tokens

Context

  • Usage of Ruby programming language for web development
  • Usage of Ruby on Rails for building web applications

Description

Non compliant code

        class SessionsController < ApplicationController
  def create
    user = User.find_by(email: params[:email])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      redirect_to root_url, :notice => "Logged in!"
    else
      flash.now.alert = "Invalid email or password"
      render "new"
    end
  end

  def destroy
    session[:user_id] = nil
    redirect_to root_url, :notice => "Logged out!"
  end
end
        
        

This is a simple Ruby on Rails controller for handling user sessions. The create method is used to authenticate a user with their email and password. If the user is authenticated successfully, their user ID is stored in the session and they are redirected to the root URL. The destroy method is used to log out a user by setting the user_id in the session to nil.

The vulnerability in this code lies in the fact that the session ID is stored in the URL. This means that if an attacker has access to the browsing history, they can retrieve the session ID and potentially hijack the user's session. This is a serious security risk as it could allow an attacker to impersonate a user and perform actions on their behalf.

This vulnerability could be exploited if an attacker has local access to the machine, or if they are able to intercept the user's network traffic. In the latter case, the attacker could retrieve the session ID from the URL as it is transmitted over the network.

In addition to this, URL parameters are often logged by web servers, and these logs may be accessible to unauthorized users. If the session ID is included in the URL, it could be exposed in these logs, providing another potential attack vector.

Furthermore, URLs can be leaked through the Referer header. When a user clicks on a link, the URL of the page they are coming from is often sent in the Referer header of the HTTP request. If the session ID is included in the URL, it could be exposed in this way.

Finally, URLs are displayed in the address bar of the browser, and could potentially be seen by others who have access to the user's screen.

In summary, transmitting session IDs in the URL is a significant security risk, as it exposes the session ID in a number of ways, increasing the likelihood of session hijacking attacks.

Steps

  • Do not send sensitive information via URL parameters.
  • Use HTTP POST method to send sensitive information.
  • Store the JWT session token securely on the server-side.
  • Use secure cookies or session management techniques to store and retrieve the session token.
  • Implement CSRF protection to prevent cross-site request forgery attacks.
  • Ensure that the session token is not cached by the browser or stored in browser history.
  • Regularly review and update the session management mechanism to address any new vulnerabilities.

Compliant code

        class SessionsController < ApplicationController
  protect_from_forgery with: :exception

  def create
    user = User.find_by(email: params[:email])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      cookies.signed[:user_id] = { value: user.id, httponly: true, secure: Rails.env.production? }
      redirect_to root_url, notice: "Logged in!"
    else
      flash.now.alert = "Invalid email or password"
      render "new"
    end
  end

  def destroy
    session[:user_id] = nil
    cookies.delete(:user_id)
    redirect_to root_url, notice: "Logged out!"
  end
end
        
        

The updated code now uses secure cookies to store the user's session ID. The cookies.signed[:user_id] method is used to securely store the user's ID in a cookie. The httponly: true option ensures that the cookie cannot be accessed via client-side scripts, providing protection against cross-site scripting (XSS) attacks. The secure: Rails.env.production? option ensures that the cookie is only sent over HTTPS connections in a production environment, providing protection against man-in-the-middle (MITM) attacks.

The protect_from_forgery with: :exception line at the top of the controller provides CSRF protection. This ensures that all POST, PATCH, PUT, and DELETE requests must come with a valid CSRF token, or else they will be rejected.

In the destroy method, the cookies.delete(:user_id) line is used to delete the user's session ID from the cookies when the user logs out.

This approach ensures that the session token is not sent via URL parameters, and is not cached by the browser or stored in browser history. It also provides protection against CSRF and XSS attacks. Regularly reviewing and updating the session management mechanism will help to address any new vulnerabilities that may arise.

References