Skip to main content

Technical information leak - Errors

Need

Prevention of technical information leaks through error messages

Context

  • Usage of Ruby for building dynamic and object-oriented applications
  • Usage of ActionController for handling actions and requests in a Ruby on Rails application
  • Usage of ActionController::API for building API controllers in Ruby on Rails
  • Usage of the User dependency for managing user-related functionality

Description

Non compliant code

class ApplicationController < ActionController::API
def create
@user = User.new(user_params)

if @user.save
render json: @user, status: :created
else
render json: @user.errors, status: :unprocessable_entity
end
end

private

def user_params
params.require(:user).permit(:username, :email, :password)
end
end

In the above code, the create method in ApplicationController is used to create a new user. The user's details are received from the client-side in the request body. These details are then used to create a new user object (@user = User.new(user_params)). If the user object is successfully saved (@user.save), the server responds with a status of :created and the user's details.

However, if there is an error while saving the user object, the server responds with a status of :unprocessable_entity and the details of the errors (render json: @user.errors). This is where the vulnerability lies.

By responding with the details of the errors, the server leaks technical information to the client. An attacker can send various types of requests to the server (e.g., massive requests to the endpoint, sending massive characters in the body of the request) to force the server to throw errors. By analyzing the error details, the attacker can gain insights into the internal workings of the server, which they can then exploit to launch more sophisticated attacks.

Steps

  • Implement proper error handling and error messages to avoid leaking sensitive technical information.
  • Avoid displaying detailed error messages to the user in the production environment.
  • Use generic error messages instead of specific error messages that could reveal implementation details.
  • Consider logging the errors for debugging purposes, but ensure that the logged information does not contain sensitive technical details.
  • Regularly review and update error handling mechanisms to address any potential vulnerabilities.

Compliant code

class ApplicationController < ActionController::API
def create
@user = User.new(user_params)

if @user.save
render json: @user, status: :created
else
render json: { error: 'Unable to process your request' }, status: :unprocessable_entity
end
rescue => e
render json: { error: 'Internal server error' }, status: :internal_server_error
Rails.logger.error e.message
end

private

def user_params
params.require(:user).permit(:username, :email, :password)
end
end

The updated code includes a rescue block to handle any unexpected errors that may occur during the execution of the create method. This prevents the server from leaking technical information about the error to the client. Instead, a generic error message is returned to the client.

In the case of a failed user save operation, instead of returning the specific error messages generated by the @user.errors object, a generic error message is returned. This prevents potential attackers from gaining insights into the application's implementation details.

The error message is also logged using Rails.logger.error for debugging purposes. This allows developers to investigate the error in the server logs without exposing sensitive information to the client.

Remember to ensure that your server logs do not contain sensitive information and are properly protected against unauthorized access. Regularly review and update your error handling mechanisms to address any potential vulnerabilities.

References