Missing cURL timeout in get_country() causes indefinite hang on slow/dead upstream #4

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

Problem

The cURL request to ipapi.co in get_country() sets no connection or transfer timeout:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://ipapi.co/".$ip."/country_name");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);

CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT are never set.

Location

message.php, lines 26–35

Risk

If ipapi.co is slow, unresponsive, or experiencing an outage, every call to message.php (i.e. every message submission) blocks the PHP worker until PHP's own max_execution_time expires (default 30 s, but often set higher or disabled). Under concurrent load this exhausts all available PHP-FPM workers, causing a denial of service for the entire application.

Suggested fix direction

Add explicit timeouts:

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);

Also consider making the geo-lookup asynchronous or falling back gracefully to "Unknown" when the upstream is slow.

Severity

moderate

Found by

Automated audit by Claude Code

## Problem The cURL request to `ipapi.co` in `get_country()` sets no connection or transfer timeout: ```php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://ipapi.co/".$ip."/country_name"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); ``` `CURLOPT_CONNECTTIMEOUT` and `CURLOPT_TIMEOUT` are never set. ## Location `message.php`, lines 26–35 ## Risk If `ipapi.co` is slow, unresponsive, or experiencing an outage, every call to `message.php` (i.e. every message submission) blocks the PHP worker until PHP's own `max_execution_time` expires (default 30 s, but often set higher or disabled). Under concurrent load this exhausts all available PHP-FPM workers, causing a denial of service for the entire application. ## Suggested fix direction Add explicit timeouts: ```php curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); curl_setopt($ch, CURLOPT_TIMEOUT, 5); ``` Also consider making the geo-lookup asynchronous or falling back gracefully to `"Unknown"` when the upstream is slow. ## 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#4
No description provided.