Technical information leak - Print Functions - Ruby

Technical information leak - Print Functions - Ruby

Need

Prevention of sensitive information exposure through print functions

Context

  • Usage of Ruby 2.7 for Ruby programming and development
  • Usage of Rails framework for building web applications

Description

Non compliant code

        def login
  begin
    user = User.find_by_username(params[:username])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      redirect_to root_url, notice: "Logged in!"
    else
      flash.now.alert = "Email or password is invalid"
      render "new"
    end
  rescue => e
    puts e.message
    puts e.backtrace.inspect
  end
end
        
        

The above Ruby code is a simple login function for a web application using the Ruby on Rails framework. The function takes a username and password from the user, checks if the user exists and if the password is correct, and then logs the user in if the check is successful.

The vulnerability lies in the rescue block. If an exception occurs during the login process, the code uses puts to print the error message and the backtrace to the console. This is a technical information leak, as it may expose sensitive information about the application's structure, data, or functionality.

In a production environment, this information could be seen by anyone who has access to the server logs. This is especially dangerous if the error messages or backtrace include sensitive information, such as user data or details about the server's file system.

This kind of information leak can be exploited by attackers to gather information for more targeted attacks, to exploit other vulnerabilities in the application, or to gain unauthorized access to data.

Steps

  • Remove the print functions (puts, print, etc.) from the code.
  • Instead of printing the error message and backtrace, handle the exception appropriately.
  • Consider logging the error message and backtrace to a log file instead of printing them to stdout.
  • Ensure that sensitive information is not exposed in error messages or logs.
  • Implement proper error handling and error messages to provide meaningful feedback to the user without revealing technical information.

Compliant code

        def login
  begin
    user = User.find_by_username(params[:username])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      redirect_to root_url, notice: "Logged in!"
    else
      flash.now.alert = "Email or password is invalid"
      render "new"
    end
  rescue => e
    Rails.logger.error "Error: #{e.message}"
    Rails.logger.error "Backtrace: #{e.backtrace.inspect}"
    flash.now.alert = "An error occurred. Please try again."
    render "new"
  end
end
        
        

The original code was vulnerable due to the use of puts to print error messages and backtraces to stdout. This could potentially expose sensitive information about the application.

The fixed code removes the puts statements and instead logs the error message and backtrace using Rails.logger.error. This ensures that the error information is recorded for debugging purposes, but is not exposed to the user or anyone who might be watching the stdout.

Additionally, the fixed code adds a generic error message to be displayed to the user in case of an exception. This message does not reveal any technical information about the error, but simply informs the user that an error occurred and prompts them to try again.

This way, the code maintains its functionality and provides meaningful feedback to the user, while also protecting sensitive application information.

References