T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:57
- Finding
- Unsafe Shell Command and API Request Construction<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 57–82 **Vulnerability Type**: Command injection and unsafe request construction **Risk Level**: High ### Vulnerable Code ```bash curl -s -X GET \ -H "Authorization: Bearer $HC_API_KEY" \ -H "Content-Type: application/json" \ "https://api.help.center/v0/centers/$HC_CENTER_ID/articles?search=SEARCH_TERM&expand[]=content" ``` ```bash curl -s -X GET \ -H "Authorization: Bearer $HC_API_KEY" \ -H "Content-Type: application/json" \ "https://api.help.center/v0/centers/$HC_CENTER_ID/articles/ARTICLE_ID?expand[]=content" ``` ```bash curl -s -X PATCH \ -H "Authorization: Bearer $HC_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Updated Title", "html": "<h1>Updated full HTML content with changes merged in</h1>" }' \ "https://api.help.center/v0/centers/$HC_CENTER_ID/articles/ARTICLE_ID/draft" ``` The same unsafe request-generation pattern is repeated in the create, category-management, image-upload, and metadata examples at lines 112–123, 192–215, 231–234, and 272–282. ### Technical Analysis The Skill instructs an agent to construct executable `curl` commands by replacing placeholders with search terms, article identifiers, titles, HTML content, and file paths. It does not require URL encoding, JSON serialization, strict identifier validation, or execution through an argument-safe API. The update request places generated article content inside a single-quoted shell argument. Article HTML or titles containing an apostrophe can terminate the shell string. If the agent performs direct textual substitution, additional shell syntax may then be interpreted as arguments, redirections, command substitutions, or separate commands. Normal content can also produce malformed JSON even when no malicious input is present. Likewise, inserting an unencoded search term directly into a URL can modify query semantics. If an agent generates shell source rather than p ...[truncated 2859 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Do not construct shell source through textual substitution.** Prefer a typed HTTP client. If `curl` is necessary, invoke it through an argument-array interface so each value remains a single argument and is never reparsed as shell syntax. 2. **Serialize JSON using a JSON-aware tool.** For example: ```bash payload="$( jq -n \ --arg title "$ARTICLE_TITLE" \ --arg html "$ARTICLE_HTML" \ '{title: $title, html: $html}' )" curl --fail-with-body --silent --show-error \ -X PATCH \ -H "Authorization: Bearer $HC_API_KEY" \ -H "Content-Type: application/json" \ --data-binary "$payload" \ "$DRAFT_URL" ``` 3. **URL-encode all query parameters.** Use `curl --get --data-urlencode` rather than concatenating search input into the URL: ```bash curl --fail-with-body --silent --show-error \ --get \ -H "Authorization: Bearer $HC_API_KEY" \ -H "Content-Type: application/json" \ --data-urlencode "search=$SEARCH_TERM" \ --data-urlencode "expand[]=content" \ "https://api.help.center/v0/centers/$HC_CENTER_ID/articles" ``` 4. **Validate identifiers before constructing endpoint paths.** Enforce the documented Center ID, article ID, and category ID formats with strict allowlists. Reject path separators, traversal sequences, control characters, whitespace, URL delimiters, and values outside the expected length. 5. **Restrict file uploads.** Require an explicit user-approved path, resolve it to a canonical path, ensure it resides in an authorized workspace or upload directory, reject symbolic-link escapes, verify the actual file type and size, and show the resolved path before transmission. 6. **Enforce least-privilege API scopes.** Request only `content.read` for read operations, add `content.write` only when editing is needed, and keep `content.publish` and `content.delete` optional. Recommend separate narrowly scoped keys where the platform ...[truncated 263 chars]
