Automatic information enumeration - Credit Cards - PHP

Automatic information enumeration - Credit Cards - PHP

Need

Enhancement of credit card validation and security measures

Context

  • Usage of PHP 7.0 for server-side scripting and web development
  • Usage of Illuminate\\Http\\Request for handling HTTP requests in Laravel
  • Usage of the CreditCard model in the App\\Models namespace

Description

Non compliant code

        card_number)->first();
        return response()->json($creditCard);
    }
}
        
        

In the code above, the getCreditCardDetails function in the CreditCardController class fetches the credit card details based on the card number provided in the request without validating whether the request is coming from an authenticated and authorized user. It's using Laravel's Eloquent ORM to fetch the credit card details from the database.

The vulnerability here is that anyone who knows a card number can retrieve the associated card's details, including sensitive information like the card's expiration date and security code. This is a serious security issue as it could lead to credit card information theft and unauthorized transactions.

This vulnerability is due to a lack of proper access control and validation of requests. The system should not expose sensitive information without validating the requester's identity and their authorization to access such information.

Steps

  • Add authentication middleware to the controller to ensure only authorized users can access the credit card details.
  • Implement input validation to check if the provided card number is valid and belongs to the authenticated user.
  • Encrypt sensitive data such as the card number, expiration date, and security code in the database.
  • Do not return sensitive data like the security code and expiration date in the API response. If necessary, mask part of the card number.
  • Implement rate limiting to prevent brute force attacks or automated enumeration of card details.

Compliant code

        middleware('auth');
    }

    public function getCreditCardDetails(Request $request)
    {
        $request->validate([
            'card_number' => 'required|exists:credit_cards,card_number,user_id,' . Auth::id(),
        ]);

        $creditCard = CreditCard::where('card_number', Crypt::encrypt($request->card_number))
                                ->where('user_id', Auth::id())
                                ->first(['card_number', 'card_holder_name']);

        if ($creditCard) {
            $creditCard->card_number = '**** **** **** ' . substr($creditCard->card_number, -4);
        }

        return response()->json($creditCard);
    }
}
        
        

The updated code includes several security measures to prevent automatic information enumeration of credit card details.

1. Authentication Middleware: The __construct method now includes a middleware that ensures only authenticated users can access the getCreditCardDetails method.

2. Input Validation: The getCreditCardDetails method now validates the incoming request to ensure the card_number is provided and exists in the credit_cards table for the authenticated user.

3. Data Encryption: The card_number is now encrypted before being stored in the database using Laravel's Crypt facade. This ensures that even if the database is compromised, the credit card details will not be exposed.

4. Limited Data Exposure: The getCreditCardDetails method now only returns the card_number and card_holder_name. The card_number is also masked, with only the last four digits visible.

5. Rate Limiting: Although not shown in the code, it is recommended to implement rate limiting on this endpoint to prevent brute force attacks or automated enumeration of card details. This can be done using Laravel's built-in rate limiting features.

References