T09 · Insecure Skill Coding Practices
- Location
src/tools/get-post.ts:41- Finding
Unvalidated Post Identifier Allows Authenticated API Path Manipulation
- Content
View full analysis
=> { const data = await poststashFetch(`/posts/${input.post_id}`) as { post: PostObject; analytics: PostAnalytics[]; }; return { post: data.post, analytics: data.analytics, }; }, }; ``` The resulting path is passed to the authenticated network client in `src/client.ts`: ```ts const res = await fetch(`${BASE}${path}`, { ...init, headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", ...init.headers, }, }); ``` ### Technical Analysis The tool declares `post_id` as an unrestricted string even though its description states that it must be a UUID. It then interpolates that value directly into the request path without strict UUID validation or path-component encoding. An attacker who can influence tool arguments may supply path-control characters or traversal segments such as `/`, `..`, `?`, or `#`. URL parsing and normalization can consequently transform the intended endpoint: ```text https://poststash.com/api/posts/{UUID} ``` into a different same-origin endpoint. For example, a value containing traversal segments can escape the intended `/api/posts/` route. The shared client will still attach `POSTSTASH_API_KEY` as a bearer credential to the resulting request. The destination origin remains fixed to `https://poststash.com`, so this is not a general serv ...[truncated 1926 chars]- Remediation
View remediation
=> { if (!UUID_PATTERN.test(input.post_id)) { throw new Error("post_id must be a valid UUID"); } const encodedPostId = encodeURIComponent(input.post_id); const data = await poststashFetch(`/posts/${encodedPostId}`) as { post: PostObject; analytics: PostAnalytics[]; }; return { post: data.post, analytics: data.analytics, }; }, ``` 3. **Constrain paths in the shared client** Where practical, avoid accepting arbitrary paths in `poststashFetch`. Introduce route-specific helpers or reject paths containing traversal segments, fragments, unexpected query strings, or absolute-URL syntax. 4. **Retain server-side authorization controls** PostStash should independently authorize every endpoint and resource against the bearer credential. Client-side validation reduces attack surface but must not replace server-side access control. 5. **Add negative security tests** Test identifiers containing values such as `../`, encoded traversal characters, `/`, `?`, `#`, absolute URLs, and malformed UUIDs. Confirm that these inputs are rejected before any network request is issued. ]]>
