T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:196
- Finding
- Shell Command Injection Through Unvalidated User-Controlled Values<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:196-254` **Vulnerability Type**: Shell command injection in instruction-defined `exec` operations **Risk Level**: High ### Vulnerable Code ```bash curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \ -H "Content-Type: application/json" \ -d "{ \"app_id\": \"$APP_ID\", \"app_secret\": \"$APP_SECRET\" }" ``` ```bash curl -s -X POST "https://open.feishu.cn/open-apis/drive/v1/permissions/{FILE_TOKEN}/members/batch_create?type={DOC_TYPE}" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer {tenant_access_token}" \ -d "{ \"members\": [{ \"member_type\": \"openid\", \"member_id\": \"$OWNER_OPEN_ID\", \"perm\": \"full_access\" }] }" ``` The associated parsing instructions state that the document token is extracted from a document URL supplied by the user. The only documented processing is to select the final path segment and remove query-string or fragment suffixes. The Open ID validation described elsewhere only verifies that the value starts with `ou_`. ### Technical Analysis Although the repository contains instructions rather than an executable script, those instructions direct the Agent to construct shell commands and execute them through `exec`. Values originating from configuration, conversation context, or a user-supplied URL are interpolated into double-quoted shell strings without strict validation or shell-safe argument handling. Double quotes do not suppress command substitution such as `$(command)` or backtick substitution. A value that passes the weak `ou_` prefix check, such as one containing `ou_$(...)`, can therefore cause the shell to execute the embedded command. A crafted document token can create the same condition when inserted into the quoted URL. The implementation does not specify an anchored allowlist for document tokens, Open IDs, document types, application IDs, or secrets. ...[truncated 1428 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace shell-based `curl` execution with a structured HTTP client or trusted HTTP tool that accepts URL, headers, and JSON bodies as separate typed parameters. 2. If process execution is unavoidable, invoke the executable with an argument array and explicitly disable shell interpretation. 3. Apply anchored allowlists before using any value: - Open ID: `^ou_[A-Za-z0-9_-]+$` - File token: `^[A-Za-z0-9_-]+$` - App ID: `^cli_[A-Za-z0-9_-]+$` - Document type: accept only `bitable`, `docx`, `doc`, `sheet`, `folder`, `file`, or `wiki`. 4. Parse user URLs with a standards-compliant URL parser. Require HTTPS and validate the hostname against explicitly trusted Feishu domains before extracting a token. 5. Construct request bodies with a JSON serializer rather than string interpolation. 6. Reject control characters, quotes, whitespace, shell substitutions, and encoded forms that decode to disallowed characters. 7. Run the Agent with least operating-system privilege and prevent it from reading unrelated secrets where possible. ]]>
