Automatic information enumeration - Credit Cards
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
<?php
namespace App\\Http\\Controllers;
use Illuminate\\Http\\Request;
use App\\Models\\CreditCard;
class CreditCardController extends Controller
{
public function getCreditCardDetails(Request $request)
{
$creditCard = CreditCard::where('card_number', $request->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
<?php
namespace App\\Http\\Controllers;
use Illuminate\\Http\\Request;
use App\\Models\\CreditCard;
use Illuminate\\Support\\Facades\\Auth;
use Illuminate\\Support\\Facades\\Crypt;
class CreditCardController extends Controller
{
public function __construct()
{
$this->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.
-
Authentication Middleware: The
__construct
method now includes a middleware that ensures only authenticated users can access thegetCreditCardDetails
method. -
Input Validation: The
getCreditCardDetails
method now validates the incoming request to ensure thecard_number
is provided and exists in thecredit_cards
table for the authenticated user. -
Data Encryption: The
card_number
is now encrypted before being stored in the database using Laravel'sCrypt
facade. This ensures that even if the database is compromised, the credit card details will not be exposed. -
Limited Data Exposure: The
getCreditCardDetails
method now only returns thecard_number
andcard_holder_name
. Thecard_number
is also masked, with only the last four digits visible. -
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.