logo

Lack of data validation - Numbers - Ruby


Need

Implementation of robust data validation for numbers


Context

  1. Requirement of Ruby 2.0+ for running the application
  2. Usage of Ruby on Rails framework for web application development

Description

Insecure Code Example

def update_user_age
  age = params[:age]
  @user = User.find(params[:id])
  @user.update_attribute(:age, age)
end

The above vulnerable code is a typical example of a lack of data validation in a Ruby on Rails backend application. In the `update_user_age` method, the `age` parameter is directly fetched from the request parameters without any form of validation or sanitation. This `age` value is then used to update the `age` attribute of a `User` object. The vulnerability lies in the fact that an attacker can pass in any value for the `age` parameter, including negative numbers, extremely large numbers, or non-numeric values. This can break the application's business logic, as age is typically a positive integer and within a certain range. For instance, an attacker could pass in a negative number for age, which is logically incorrect as age cannot be negative. Similarly, an attacker could pass in a non-numeric value for age, which could potentially cause a type error in the application, leading to unexpected behavior or crashes. This lack of data validation can lead to various negative impacts on the business, including incorrect data being stored in the database, application crashes leading to service downtime, and potential exploitation of other vulnerabilities due to unexpected input.

Steps

  1. Implement input validation to ensure that the 'age' parameter is a valid number.
  2. Use a validation method or regular expression to check if the 'age' parameter is a number.
  3. Handle invalid input by displaying an error message to the user.
  4. Consider using strong parameters to whitelist and sanitize the input before updating the user's age.
  5. Ensure that the user's age is properly validated and sanitized before updating the database.
  6. Consider implementing additional business logic checks to ensure the age value is within a valid range.

Secure Code Example

def update_user_age
  age = params[:age]
  @user = User.find(params[:id])

  if valid_age?(age)
    @user.update_attribute(:age, age)
  else
    render json: { error: 'Invalid age' }, status: :unprocessable_entity
  end
end

private

def valid_age?(age)
  age.to_s.match?(/\\A[+-]?\\d+\\z/) && age.to_i.between?(0, 120)
end

The updated code includes a validation method `valid_age?` that checks if the 'age' parameter is a valid number and within a reasonable range (0 to 120 years). The `valid_age?` method uses a regular expression (`/\\A[+-]?\\d+\\z/`) to check if the 'age' parameter is a number. The `match?` method returns true if the 'age' parameter matches the regular expression, and false otherwise. The `between?` method is used to check if the 'age' parameter is within a valid range (0 to 120). This is a basic business logic check to ensure the age value is reasonable. If the 'age' parameter is not a valid number or not within the valid range, the `update_user_age` method will render a JSON response with an error message and a status code of 422 (Unprocessable Entity). If the 'age' parameter is valid, the `update_user_age` method will update the user's age in the database. This code ensures that the user's age is properly validated and sanitized before updating the database, which helps to prevent potential issues with the business logic.


References

  • 197 - Lack of data validation - Numbers

  • Last updated

    2023/09/18