Skip to main content

Insecure functionality - Masking

Need

Protection of sensitive data through proper masking techniques

Context

  • Usage of Ruby 2.7 for developing Ruby applications
  • Usage of Rails for building web applications
  • Usage of ActiveRecord for Object-Relational Mapping (ORM) in database operations

Description

Non compliant code

class UsersController < ApplicationController
def show
@user = User.find(params[:id])
end
end

The above code is a simple controller action in a Ruby on Rails application. It fetches a user based on the id parameter passed in the request and assigns it to an instance variable @user.

The vulnerability here is that the entire @user object, which may contain sensitive information such as email, password hash, or other personally identifiable information (PII), could potentially be exposed in the response if not properly handled in the view.

The show action does not perform any data masking on the @user object before it is sent to the view. This means that all attributes of the @user object are accessible in the view, and if the view inadvertently (or intentionally) displays sensitive attributes, this could lead to a data exposure vulnerability.

For example, if the corresponding view (show.html.erb) contains something like this:

<p>
<strong>Email:</strong>
<%= @user.email %>
</p>

<p>
<strong>Password hash:</strong>
<%= @user.password_digest %>
</p>

This would expose the user's email and password hash in the response, which is a serious security issue.

Even if the view does not currently display any sensitive information, it is still a good practice to mask or filter the data in the controller to prevent potential future vulnerabilities if the view is modified.

Steps

  • Implement data masking for sensitive information in the request and response.
  • Identify the sensitive data that needs to be masked, such as passwords, social security numbers, or credit card numbers.
  • Use appropriate methods or libraries to mask the sensitive data before sending it in the response.
  • Ensure that the masked data cannot be easily reversed or decrypted.
  • Implement input validation and sanitization to prevent the exposure of sensitive data in the request.
  • Consider using encryption or tokenization techniques to further protect sensitive data.
  • Regularly review and update the data masking implementation to address any new vulnerabilities or changes in the application.
  • Perform thorough testing to ensure that the data masking is working correctly and effectively.
  • Educate developers and other stakeholders about the importance of data masking and the potential risks of exposing sensitive information.

Compliant code

class UsersController < ApplicationController
def show
@user = User.find(params[:id])
mask_sensitive_data(@user)
end

private

def mask_sensitive_data(user)
user.email = mask_email(user.email)
user.password = mask_password(user.password)
# Add any other sensitive fields that need to be masked
end

def mask_email(email)
# Implement your email masking logic here
end

def mask_password(password)
# Implement your password masking logic here
end
end

The updated code includes a new method mask_sensitive_data that is called in the show action. This method takes a user object as an argument and masks the sensitive data fields. In this case, we are masking the email and password fields, but you can add any other fields that contain sensitive data.

The mask_email and mask_password methods are placeholders for your actual masking logic. You can implement these methods to mask the data in a way that suits your needs. For example, you could replace certain characters with asterisks, or use a library that provides data masking functionality.

Remember that the goal of data masking is to prevent sensitive data from being exposed in the response. Therefore, the masking should be done in a way that the original data cannot be easily reversed or decrypted.

In addition to data masking, you should also implement input validation and sanitization to prevent the exposure of sensitive data in the request. This could involve checking that the input data is in the correct format, removing any potentially harmful characters, and so on.

Finally, consider using encryption or tokenization techniques to further protect sensitive data. This could involve replacing the sensitive data with a token that can only be used to retrieve the original data from a secure location.

Regularly review and update your data masking implementation to address any new vulnerabilities or changes in your application. Perform thorough testing to ensure that the data masking is working correctly and effectively. And educate your developers and other stakeholders about the importance of data masking and the potential risks of exposing sensitive information.

References