Log injection - Ruby

Log injection - Ruby

Need

Prevention of log injection attacks

Context

  • Usage of Ruby 2.0+ for developing Ruby applications
  • Usage of Rails framework for building web applications

Description

Non compliant code

        def create
  @user = User.new(user_params)
  if @user.save
    logger.info "User created: #{@user.inspect}"
    redirect_to @user, notice: 'User was successfully created.'
  else
    render :new
  end
end
        
        

In the above Ruby on Rails code snippet, the create method is responsible for creating a new user. The user's information is logged if the user is successfully saved.

The vulnerable part of the code is the line logger.info "User created: #{@user.inspect}". This line logs the entire user object, which includes all the user input. If an attacker provides malicious input (for example, input containing script tags or SQL commands), this input will be logged as is.

This is a problem because logs are often displayed in various places (like a monitoring dashboard) or stored in a way that doesn't expect this kind of input. As a result, an attacker could exploit this to perform attacks such as Cross-Site Scripting (XSS) or SQL Injection through the log entries.

The vulnerability could be even more dangerous if the logs are parsed by other systems or used in a way that could lead to code execution (for example, if the logs are used to generate dynamic SQL queries).

This is a classic example of a Log Injection vulnerability because the application logs entries that contain input from untrusted sources without properly validating, sanitizing or escaping their content.

Steps

  • Validate and sanitize user input before logging it
  • Use a logging library that automatically escapes or sanitizes log entries
  • Avoid logging sensitive information
  • Implement a logging policy to restrict the types of information that can be logged

Compliant code

        def create
  @user = User.new(user_params)
  if @user.save
    sanitized_user = ActionController::Base.helpers.sanitize(@user.inspect)
    logger.info "User created: #{sanitized_user}"
    redirect_to @user, notice: 'User was successfully created.'
  else
    render :new
  end
end
        
        

The above code fixes the log injection vulnerability by sanitizing the user input before logging it. The ActionController::Base.helpers.sanitize method is used to sanitize the user input. This method removes any malicious characters or scripts from the input, thus preventing log injection attacks.

In the original code, the user input was directly logged without any validation or sanitization. This could allow an attacker to inject malicious scripts or commands into the logs, which could then be executed when the logs are viewed or processed.

By sanitizing the user input, we ensure that any malicious content is removed before it is logged. This prevents log injection attacks and helps to keep the system secure.

In addition to sanitizing user input, it's also important to avoid logging sensitive information, such as passwords or credit card numbers. This can help to further protect the system from potential attacks.

Finally, implementing a logging policy can help to restrict the types of information that can be logged. This can prevent sensitive or potentially harmful information from being logged, further enhancing the security of the system.

References