HIGH pii leakagegrape

Pii Leakage in Grape

How PII Leakage Manifests in Grape

PII leakage in Grape APIs typically occurs through several Grape-specific patterns. The most common is improper serialization of ActiveRecord objects in API responses. When developers use Grape's present method without explicitly specifying attributes, all model attributes—including sensitive ones like email, phone_number, or ssn—are exposed by default.

# Vulnerable Grape endpoint
class UsersAPI < Grape::API
  format :json

  desc 'Get user details'
  get '/users/:id' do
    user = User.find(params[:id])
    present user, with: Entities::User
  end
end

# Entity exposing all attributes
class Entities::User < Grape::Entity
  expose :all
end

This code would leak all user attributes, including PII, because expose :all serializes every column from the database table. Another common Grape-specific vulnerability occurs with dynamic response building using present without entity classes:

# Vulnerable dynamic response
get '/users/:id' do
  user = User.find(params[:id])
  present user, with: { email: user.email, phone: user.phone_number }
end

While this seems safe, if the response object structure changes or if additional attributes are added to the user object, PII can inadvertently be exposed. Grape's flexible parameter handling also creates PII leakage risks when sensitive data is accepted in request bodies but not properly filtered before database operations:

# Vulnerable parameter handling
params do
  requires :email, type: String
  requires :password, type: String
  requires :ssn, type: String
end

Here, the SSN parameter is accepted but might be stored or logged without proper controls. Additionally, Grape's error handling can leak PII through detailed error messages that include stack traces or parameter dumps containing sensitive information.

Grape-Specific Detection

Detecting PII leakage in Grape APIs requires examining both the API structure and runtime behavior. Start by analyzing your Grape endpoint definitions for entity exposure patterns. Use Grape's built-in introspection to identify all exposed attributes:

# Scan for exposed attributes
class PIIScanner < Grape::API
  get '/pii_scan' do
    exposed_attrs = []
    self.class.endpoints.each do |endpoint|
      endpoint.options[:for].class.ancestors.each do |klass|
        next unless klass < Grape::Entity
        klass.exposures.each do |attr, config|
          exposed_attrs << { endpoint: endpoint.path, attribute: attr, source: config[:from] }
        end
      end
    end
    exposed_attrs
  end
end

For runtime detection, middleBrick's black-box scanning can identify PII exposure by analyzing API responses against known PII patterns. The scanner tests endpoints with synthetic data and uses regex patterns to detect PII in responses:

# Scan with middleBrick CLI
middlebrick scan https://api.example.com/users/123 --category pii

The scan tests for common PII patterns including email addresses, phone numbers, SSNs, credit card numbers, and addresses. middleBrick's LLM security module specifically checks for system prompt leakage and excessive agency patterns that could expose PII through AI-powered endpoints. For comprehensive coverage, combine static analysis of your Grape codebase with dynamic scanning:

# Static analysis script
require 'find'

pii_patterns = [/email/, /phone/, /ssn/, /credit_card/, /address/]

Find.find('app/api') do |path|
  next unless path.end_with?('.rb')
  
  File.open(path) do |file|
    file.each_line.with_index do |line, line_num|
      if line.include?('expose') && pii_patterns.any? { |pattern| line.match?(pattern) }
        puts "PII exposure found: #{path}:#{line_num + 1}"
        puts line
      end
    end
  end
end

This script identifies potential PII exposure by scanning Grape entity files for sensitive attribute names in expose statements.

Grape-Specific Remediation

Remediating PII leakage in Grape requires a multi-layered approach using Grape's built-in features. First, implement strict entity definitions that explicitly control attribute exposure:

# Secure entity definition
class Entities::User < Grape::Entity
  expose :id
  expose :username
  expose :created_at
  
  # Exclude sensitive attributes
  # expose :email # Remove this line
  # expose :phone_number # Remove this line
  # expose :ssn # Remove this line
end

Always use explicit entity classes rather than dynamic present calls. For attributes that need conditional exposure, use Grape's conditional exposure feature:

class Entities::User < Grape::Entity
  expose :id
  expose :username
  expose :email, if: { auth_level: :admin }
  expose :phone_number, if: { auth_level: :admin }
end

Implement parameter filtering to prevent sensitive data from being accepted in requests:

# Filter sensitive parameters
params do
  requires :username, type: String
  optional :email, type: String
  # Remove sensitive parameters
  # requires :ssn, type: String
  # requires :credit_card, type: String
end

Use Grape's before_validation hooks to sanitize incoming data:

# Sanitize sensitive data
before_validation do
  # Remove sensitive parameters from params
  %i[ssn credit_card ssn_last_four].each { |key| params.delete(key) }
  
  # Mask PII in logs
  Rails.logger.info("User login: #{params[:username]}") if params[:username]
end

For error handling, implement custom error formats that don't expose sensitive data:

# Custom error format
class ErrorFormatter < Grape::Formatter::Base
  def self.call(object, env)
    # Remove sensitive data from error responses
    error_data = object.is_a?(Hash) ? object.except(:password, :ssn, :credit_card) : object
    
    { error: error_data, status: 400 }.to_json
  end
end

# Use custom formatter
format :json, ErrorFormatter

Implement logging controls to prevent PII from being written to logs:

# Secure logging
before do
  # Mask sensitive parameters
  request.env['action_dispatch.request.parameters'].tap do |params|
    params['email'] = '***' if params['email']
    params['phone'] = '***' if params['phone']
  end
end

Finally, use middleBrick's continuous monitoring to ensure your remediations remain effective over time. The Pro plan's scheduled scanning will alert you if new PII exposure is introduced through code changes.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

How does middleBrick detect PII leakage in Grape APIs?
middleBrick uses black-box scanning to test your API endpoints with synthetic data, then analyzes responses using regex patterns for PII like emails, phone numbers, SSNs, and addresses. It also checks for system prompt leakage in LLM endpoints and excessive agency patterns. The scanner provides a security score with severity levels and actionable remediation guidance.
Can middleBrick scan my Grape API without access to the source code?
Yes, middleBrick is a black-box scanner that requires no source code access, credentials, or agents. Simply provide your API URL and middleBrick will test the unauthenticated attack surface, including PII leakage detection, in 5-15 seconds. It works with any API framework, including Grape.