SSRF: unvalidated REMOTE_ADDR concatenated into cURL URL in get_country() #3

Open
opened 2026-05-14 21:14:44 +02:00 by Claude · 0 comments

Problem

get_country() in message.php constructs a cURL URL by directly concatenating $_SERVER['REMOTE_ADDR'] with no format validation:

curl_setopt($ch, CURLOPT_URL, "https://ipapi.co/".$ip."/country_name");

There is no check that $ip is a valid IPv4 or IPv6 address before it is placed into the URL.

Location

message.php, lines 22–38

Risk

In misconfigured reverse-proxy or load-balancer setups where the application server treats a forwarded header (e.g. X-Forwarded-For, X-Real-IP) as REMOTE_ADDR, an attacker can supply an arbitrary value. A crafted value such as 127.0.0.1@internal-host/secret or a path-traversal sequence can redirect the cURL request to internal services (SSRF), potentially leaking cloud metadata endpoints (e.g. 169.254.169.254), internal APIs, or other services not exposed to the internet.

Suggested fix direction

Validate $ip strictly with filter_var($ip, FILTER_VALIDATE_IP) and return "Unknown" for any value that doesn't pass. This ensures only well-formed IP addresses reach the URL.

Severity

moderate

Found by

Automated audit by Claude Code

## Problem `get_country()` in `message.php` constructs a cURL URL by directly concatenating `$_SERVER['REMOTE_ADDR']` with no format validation: ```php curl_setopt($ch, CURLOPT_URL, "https://ipapi.co/".$ip."/country_name"); ``` There is no check that `$ip` is a valid IPv4 or IPv6 address before it is placed into the URL. ## Location `message.php`, lines 22–38 ## Risk In misconfigured reverse-proxy or load-balancer setups where the application server treats a forwarded header (e.g. `X-Forwarded-For`, `X-Real-IP`) as `REMOTE_ADDR`, an attacker can supply an arbitrary value. A crafted value such as `127.0.0.1@internal-host/secret` or a path-traversal sequence can redirect the cURL request to internal services (SSRF), potentially leaking cloud metadata endpoints (e.g. `169.254.169.254`), internal APIs, or other services not exposed to the internet. ## Suggested fix direction Validate `$ip` strictly with `filter_var($ip, FILTER_VALIDATE_IP)` and return `"Unknown"` for any value that doesn't pass. This ensures only well-formed IP addresses reach the URL. ## Severity moderate ## Found by Automated audit by Claude Code
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bc1bb/OpenLongr#3
No description provided.