T09 · Insecure Skill Coding Practices
Error
- Location
- src/services/media.ts:1022
- Finding
- Arbitrary Local File Disclosure Through Agent-Generated Paths<![CDATA[ ## Vulnerability Details **File Location**: `src/services/media.ts:1022-1109`; `src/services/media/common.ts:65-137`; callers at `src/core/message-handler.ts:1507-1508` and `src/reply-dispatcher.ts:328-330` **Vulnerability Type**: Arbitrary local file read and upload **Risk Level**: High ### Vulnerable Code ```ts export async function processRawMediaPaths( content: string, config: DingtalkConfig, oapiToken: string, log?: any, target?: AICardTarget, ): Promise<string> { const logPrefix = 'RawMedia'; const rawPathPattern = /(?:^|\s)((?:[A-Za-z]:)?[\/\\](?:[^\/\\:\*\?"<>\|\s]+[\/\\])*[^\/\\:\*\?"<>\|\s]+\.(?:mp4|avi|mov|wmv|flv|mkv|webm|mp3|wav|flac|aac|ogg|m4a|wma|pdf|doc|docx|xls|xlsx|ppt|pptx|txt|zip|rar|7z|tar|gz))(?:\s|$)/gi; const matches = Array.from(content.matchAll(rawPathPattern)); if (matches.length === 0) { return content; } for (const match of matches) { const fullMatch = match[0]; const filePath = match[1].trim(); const uploadResult = await uploadMediaToDingTalk( filePath, mediaType, oapiToken, 20 * 1024 * 1024, log ); ``` The upload implementation accepts the supplied path without restricting it to an approved workspace: ```ts const absPath = toLocalPath(filePath); log?.info?.(`检查文件是否存在:${absPath}`); if (!fs.existsSync(absPath)) { log?.warn?.(`文件不存在:${absPath}`); return null; } const stats = fs.statSync(absPath); const form = new FormData(); form.append('media', fs.createReadStream(absPath), { filename: path.basename(absPath), contentType: mediaType === 'image' ? 'image/jpeg' : 'application/octet-stream', }); const resp = await dingtalkUploadHttp.post( `${DINGTALK_OAPI}/media/upload`, form, { params: { access_token: oapiToken, type: mediaType }, headers: form.getHeaders(), timeout: 60_000, maxBodyLength: Infinity, }, ); ``` ### Technical Analysis The connector scans agent-generated response text for absolute local paths with ...[truncated 2246 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove automatic processing of arbitrary absolute paths from model output. 2. Require media to be represented by opaque attachment identifiers rather than filesystem paths. 3. If path-based exports must remain supported: - Resolve the candidate and allowed root using `fs.realpathSync()`. - Require the canonical candidate path to remain inside a dedicated per-session export directory. - Reject symbolic links and non-regular files. - Reject files not created for the current request. 4. Do not allow access to home, root, configuration, credential, temporary files belonging to other sessions, or arbitrary operating-system directories. 5. Require explicit confirmation from an authenticated, authorized user before uploading a local file. 6. Bind generated artifacts to the requesting session using server-side metadata. 7. Add security tests for traversal, symbolic-link escape, `/root`, `/home`, Windows drive paths, cross-session files, and prompt-induced path disclosure. 8. Avoid logging full sensitive paths unless debug logging has been explicitly enabled. ]]>
