-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
DoraCMS 3.1 Security Report (Responsible Disclosure)
Report Title: SSRF via UEditor Remote Image Fetch (catcher/catchImage)
Product: DoraCMS 3.1
Date: 2026-02-10
Scope: Source-code review of DoraCMS 3.1 server-side codebase
1. Executive Summary
DoraCMS 3.1 includes a Server-Side Request Forgery (SSRF) weakness in its UEditor integration. DoraCMS exposes UEditor endpoints under the upload module, and the UEditor “remote image catcher” action triggers server-side fetching of user-supplied URLs via http.request / https.request without destination restrictions (no allowlist, no private-IP blocking) or resource safety controls (no timeout, no max response size, no redirect policy).
If reachable by untrusted users, this enables attackers to induce the DoraCMS server to make outbound requests to arbitrary destinations, potentially including internal services. Additionally, the implementation buffers remote responses into memory and writes the fetched content into a public upload directory, increasing potential impact and enabling denial-of-service conditions.
2. Context: UEditor in DoraCMS is used for File Upload
DoraCMS integrates UEditor as part of its file upload functionality. This is evident from server/app/router/api/v1.js, where UEditor routes are grouped under the file upload section and are handled by the same uploadFile controller used for upload endpoints.
Evidence (Source Code)
File: server/app/router/api/v1.js
// ==================== 文件上传 ====================
router.post('/api/v1/files', authApiToken, controller.api.uploadFile.create);
router.post('/api/v1/files/path', authApiToken, controller.api.uploadFile.createFileByPath);
router.get('/api/v1/upload/ueditor', controller.api.uploadFile.ueditor);
router.post('/api/v1/upload/ueditor', controller.api.uploadFile.ueditor);Explanation
- The comment
// ==================== 文件上传 ====================groups these routes under DoraCMS’ upload module. /api/v1/filesand/api/v1/files/pathare authenticated upload routes./api/v1/upload/ueditor(GET/POST) is mapped tocontroller.api.uploadFile.ueditorwithin the same upload grouping, demonstrating that UEditor is part of DoraCMS’ upload implementation.
3. Vulnerability Overview
3.1 Title
Server-Side Request Forgery (SSRF) via UEditor Remote Image Fetch (catchImage)
3.2 Severity
High
3.3 OWASP Mapping
- OWASP Top 10 (2021): A10 – Server-Side Request Forgery (SSRF)
- Secondary: A05 – Security Misconfiguration (if endpoint is publicly reachable; depends on deployment)
3.4 Affected Versions
- Confirmed in DoraCMS 3.1 (source-level confirmation)
4. Affected Endpoints & Components
4.1 Routes
File: server/app/router/api/v1.js
GET /api/v1/upload/ueditorPOST /api/v1/upload/ueditor
Note: These UEditor routes are not protected by
authApiTokeninv1.js, unlike/api/v1/filesand/api/v1/files/path. If there is no other global authorization layer, exposure increases.
4.2 Vulnerable Function
File: server/app/controller/api/uploadFile.js
Function: catchImage(url)
Observed behaviors (high-level):
- Accepts a URL derived from client input.
- Performs server-side HTTP(S) request using the provided URL.
- Buffers the full response body into memory as base64.
- Returns content that is then saved to the public upload directory.
5. Technical Details
5.1 Root Cause
Untrusted input (a remote URL) is used directly in server-side HTTP request functions without:
- destination allowlisting,
- private/internal IP range blocking,
- redirect controls,
- timeouts,
- response size limits.
This creates an SSRF request primitive.
5.2 Code Evidence (Request Primitive)
File: server/app/controller/api/uploadFile.js (approx. lines 67–96)
const request = /^https:\/\//.test(url) ? https.request : http.request;
const req = request(url, res => {
res.setEncoding('base64');
res.on('data', chunk => { base64Data += chunk; });
res.on('end', () => resolve({ contentType, base64Data, originalname }));
});
req.on('error', () => resolve({ error: true }));
req.end();Key security gaps:
- No URL parsing and validation using
new URL() - No allowlist of domains/hosts
- No checks against RFC1918 / loopback / link-local ranges
- No DNS rebind defense
- No timeout on requests
- No max download size (unbounded
base64Data += chunk) - No redirect policy
5.3 Call Chain (UEditor “remote catcher” action)
File: server/app/controller/api/uploadFile.js
Method: ueditor()
When the action corresponds to the UEditor remote image catcher action, DoraCMS reads URLs from the request and calls catchImage() for each URL. The returned base64 data is then written into the public directory via upload.base64Image(...).
High-level flow:
- Router routes request to
controller.api.uploadFile.ueditor ueditor()checksctx.query.action- For the catcher action:
- reads a list of URLs from
ctx.request.body[...] - calls
catchImage(url)for each - persists fetched content to a public directory
- returns a JSON list of results
- reads a list of URLs from
6. Impact Assessment
Depending on deployment environment and network configuration, this SSRF weakness can enable:
-
Outbound request to attacker-chosen destinations
- The server becomes an HTTP client to arbitrary URLs supplied by the requester.
-
Access to internal-only services (pivoting)
- Requests can potentially reach internal hosts/services not accessible externally.
-
Potential data exposure through persisted content (environment dependent)
- Responses are buffered and saved under the upload directory; if an internal service returns sensitive content in a way that passes downstream checks, data may be written to disk.
-
Denial of Service
- Lack of timeout and response-size limit can cause:
- hanging sockets / connection exhaustion,
- memory growth from unbounded base64 buffering,
- server resource exhaustion.
- Lack of timeout and response-size limit can cause:
7. Reproduction / Verification (Safe Guidance)
To validate in an authorized test environment without targeting internal networks:
- Stand up an HTTP endpoint you control (e.g., a small logging server) that records inbound requests.
- Invoke
/api/v1/upload/ueditorwith the UEditor “remote catcher” action and provide your controlled URL in the expected request-body field. - Confirm the controlled endpoint receives a request originating from the DoraCMS server.
- Confirm DoraCMS returns success and that a file is created in the public upload directory (depending on configuration and whether the endpoint stores results).
This demonstrates that DoraCMS performs server-side outbound fetching based on user-provided URLs.
8. Recommendations
8.1 Preferred: Allowlist of Trusted Hosts
- Restrict remote fetching to a known set of domains (e.g., your CDN or approved image hosts).
- Reject IP-literal URLs unless explicitly required.
9. External Reference (Similar Vulnerability Class)
This issue matches a well-known SSRF pattern in UEditor “catchimage/catcher” implementations, similar in class to:
- PublicCMS UEditor SSRF pattern report: There is a SSRF vulnerability via /publiccms/admin/ueditor sanluan/PublicCMS#51
(Reference provided for context; DoraCMS codebase has its own independent SSRF primitive as documented above.)
End of Report