fix(security): remove JWT role extraction without signature, add OTP replay protection, fix user enumeration
This commit is contained in:
@@ -54,14 +54,12 @@ if ($count > 0) {
|
||||
]);
|
||||
// jsonError("Incorrect password.");
|
||||
}
|
||||
} else {
|
||||
// The user does not exist
|
||||
} else {
|
||||
echo json_encode([
|
||||
"status" => "Failure",
|
||||
"data" => "User does not exist."
|
||||
"data" => "Invalid credentials."
|
||||
]);
|
||||
// jsonError("User does not exist.");
|
||||
}
|
||||
$conn->close();
|
||||
}
|
||||
$con = null;
|
||||
|
||||
?>
|
||||
|
||||
@@ -18,17 +18,7 @@ if (empty($receiver)) {
|
||||
|
||||
$user_type = filterRequest("user_type");
|
||||
|
||||
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? (function_exists('apache_request_headers') ? (apache_request_headers()['Authorization'] ?? null) : null);
|
||||
if (!empty($authHeader) && preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
|
||||
$jwtToken = $matches[1];
|
||||
$tokenParts = explode('.', $jwtToken);
|
||||
if (count($tokenParts) === 3) {
|
||||
$payload = json_decode(base64_decode($tokenParts[1]), true);
|
||||
if (isset($payload['role'])) {
|
||||
$user_type = $payload['role'];
|
||||
}
|
||||
}
|
||||
}
|
||||
// user_type is taken from request only (JWT not trusted without signature verification)
|
||||
|
||||
$country = filterRequest("country"); // Egypt | Syria | Jordan
|
||||
$method = filterRequest("method"); // whatsapp | sms | voice | flash_call | bearer_send
|
||||
|
||||
@@ -23,17 +23,7 @@ if (empty($token_code)) {
|
||||
$user_type = filterRequest("user_type");
|
||||
$context = filterRequest("context"); // token_change | login (default)
|
||||
|
||||
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? (function_exists('apache_request_headers') ? (apache_request_headers()['Authorization'] ?? null) : null);
|
||||
if (!empty($authHeader) && preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
|
||||
$jwtToken = $matches[1];
|
||||
$tokenParts = explode('.', $jwtToken);
|
||||
if (count($tokenParts) === 3) {
|
||||
$payload = json_decode(base64_decode($tokenParts[1]), true);
|
||||
if (isset($payload['role'])) {
|
||||
$user_type = $payload['role'];
|
||||
}
|
||||
}
|
||||
}
|
||||
// user_type is taken from request only (JWT not trusted without signature verification)
|
||||
|
||||
if (empty($phone_number)) {
|
||||
jsonError("Phone number is required.");
|
||||
@@ -75,7 +65,7 @@ try {
|
||||
if ($user_type === 'admin') {
|
||||
$sql = "SELECT * FROM token_verification_admin
|
||||
WHERE phone_number = :phone AND token = :token
|
||||
AND expiration_time >= NOW()";
|
||||
AND expiration_time >= NOW() AND verified = 0";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':token', $encryptedToken, PDO::PARAM_STR);
|
||||
@@ -103,7 +93,7 @@ try {
|
||||
} elseif ($user_type === 'service') {
|
||||
$sql = "SELECT `id` FROM `phone_verification_service`
|
||||
WHERE `phone_number` = :phone AND `token_code` = :token
|
||||
AND `expiration_time` > NOW()";
|
||||
AND `expiration_time` > NOW() AND `is_verified` = 0";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':token', $encryptedToken, PDO::PARAM_STR);
|
||||
@@ -124,7 +114,7 @@ try {
|
||||
$sql = "SELECT `id` FROM `token_verification_driver`
|
||||
WHERE `phone_number` = :phone
|
||||
AND `token` = :token
|
||||
AND `expiration_time` > NOW()";
|
||||
AND `expiration_time` > NOW() AND `verified` = 0";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
|
||||
@@ -147,7 +137,7 @@ try {
|
||||
$sql = "SELECT `id` FROM `phone_verification`
|
||||
WHERE `phone_number` = :phone
|
||||
AND `token_code` = :token
|
||||
AND `expiration_time` > NOW()";
|
||||
AND `expiration_time` > NOW() AND `is_verified` = 0";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
|
||||
@@ -172,7 +162,7 @@ try {
|
||||
$sql = "SELECT `id` FROM `token_verification`
|
||||
WHERE `phone_number` = :phone
|
||||
AND `token` = :token
|
||||
AND `expiration_time` > NOW()";
|
||||
AND `expiration_time` > NOW() AND `verified` = 0";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
|
||||
@@ -195,7 +185,7 @@ try {
|
||||
$sql = "SELECT `id` FROM `phone_verification_passenger`
|
||||
WHERE `phone_number` = :phone
|
||||
AND `token` = :token
|
||||
AND `expiration_time` > NOW()";
|
||||
AND `expiration_time` > NOW() AND `verified` = 0";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':phone', $encryptedPhone, PDO::PARAM_STR);
|
||||
|
||||
Reference in New Issue
Block a user