T09 · Insecure Skill Coding Practices
- Location
upload.mjs:91- Finding
Unvalidated Bucket Domain Allows Upload Redirection to an Attacker-Controlled Host
- Content
View full analysis
Vulnerability Details
File Location:
upload.mjs, lines 91-117; the SDK upload path is also affected at lines 177-200
Vulnerability Type: Unvalidated network destination and credential forwarding
Risk Level: Highjs // Extract bucket name and proxy suffix const bucketName = bucket.split('.')[0]; const proxySuffix = bucket.substring(bucketName.length + 1); console.error(`[DEBUG] Bucket: ${bucketName}, Proxy: ${proxySuffix}`); const contentType = 'application/octet-stream'; const contentMD5 = ''; const date = new Date().toUTCString(); // Generate authorization signature const signature = generateSignature('PUT', bucketName, objectKey, contentType, contentMD5, date, privateKey); const authorization = `UCloud ${publicKey}:${signature}`; console.error(`[DEBUG] Authorization generated, date: ${date}`); const options = { hostname: `${bucketName}.${proxySuffix}`, port: 443, path: `/${objectKey}`, method: 'PUT', headers: { 'Authorization': authorization, 'Content-Type': contentType, 'Content-Length': fileSize, 'Date': date, }, timeout: 120000, // 120 second timeout };The same unvalidated value reaches the SDK configuration:
js // Extract bucket name from full domain // Format: bucket-name.region.ufileos.com -> bucket-name const bucketName = bucket.split('.')[0]; // Extract proxy suffix (e.g., "cn-sh2.ufileos.com") const proxySuffix = bucket.substring(bucketName.length + 1); // Create HTTP request for PUT operation const httpRequest = new ufile.HttpRequest( 'PUT', '/' + objectKey, bucketName, objectKey, filepath ); // Create auth client const authClient = new ufile.AuthClient(httpRequest, { 'ucloud_public_key': publicKey, 'ucloud_private_key': privateKey, 'proxy_suffix': proxySuffix });Technical Analysis
US3_BUCKETis accepted directly from the environment and is treated a ...[truncated 2654 chars]- Remediation
View remediation
Remediation Suggestions
- Parse
US3_BUCKETas a hostname and reject malformed values, URL schemes, ports, paths, credentials, IP literals, localhost names, and unrelated domains. - Enforce an explicit allowlist of approved UCloud US3 domain suffixes and regions. Compare normalized DNS labels rather than using a simple string-suffix check.
- Store the bucket name and service endpoint as separate configuration values. Validate the bucket name against a restrictive pattern and select the endpoint from a fixed internal mapping of approved regions.
- Do not derive a credential-bearing request destination from one unrestricted environment variable.
- Apply the same validation before both the direct HTTPS path and the SDK path.
- Use least-privilege UCloud credentials restricted to the intended bucket and required upload operations.
- Add automated tests confirming rejection of attacker-controlled domains, deceptive suffixes, IP addresses, malformed hostnames, and unexpected regions.
- Fail closed when endpoint validation is unsuccessful, and avoid logging authentication headers or signatures.
- Parse
