T09 · Insecure Skill Coding Practices
Note
- Location
- scripts/crawlora.sh:68
- Finding
- Incomplete API Route Allowlist Permits Undocumented Nested Paths## Vulnerability Details **File Location**: `scripts/crawlora.sh`, lines 68-79 **Vulnerability Type**: Incomplete route allowlist caused by overbroad shell wildcard matching **Risk Level**: Low **Vulnerable Code**: ```sh case "$path" in /bing/search) ;; /capterra/product) ;; /capterra/product/reviews) ;; /capterra/search) ;; /datasets/jobs/companies) ;; /datasets/jobs/search) ;; /extract) ;; /producthunt/product/*) ;; /producthunt/product/*/alternatives) ;; /producthunt/product/*/launches) ;; /producthunt/search) ;; /similarweb/search) ;; /similarweb/web/*) ;; /trustpilot/business-units/search) ;; /trustpilot/business/*) ;; /trustpilot/business/*/reviews) ;; /web/scrape) ;; *) echo "path is not in the competitor-intelligence skill catalog" >&2 exit 2 ;; esac ``` ### Technical Analysis Shell `case` wildcard `*` matches slash characters and therefore does not restrict a dynamic identifier to one URL path segment. Patterns such as `/producthunt/product/*`, `/similarweb/web/*`, and `/trustpilot/business/*` consequently accept arbitrary nested suffixes. The broad Product Hunt and Trustpilot patterns also precede their more specific alternatives, launches, and reviews patterns. Because `case` stops at the first match, the narrower entries do not provide additional enforcement. This undermines the script's stated route restriction: a path below one of the accepted prefixes can pass validation even when it is absent from the documented 17-endpoint catalog. The fixed HTTPS API origin prevents this flaw from redirecting the API key to an attacker-controlled host. ### Attack Path 1. An attacker or untrusted caller supplies an undocumented nested path, such as: ```sh scripts/crawlora.sh /producthunt/product/example/undocumented ``` 2. The path passes the preliminary syntax checks because it contains none of the explicitly rejected cha ...[truncated 1087 chars]
- Remediation
- ## Remediation Suggestions 1. Replace glob-based path authorization with strict regular-expression validation that permits dynamic identifiers as exactly one path segment. 2. Explicitly allow only the documented route shapes. For example: ```sh if [[ "$path" =~ ^/producthunt/product/[^/]+$ ]] || [[ "$path" =~ ^/producthunt/product/[^/]+/(alternatives|launches)$ ]] || [[ "$path" =~ ^/similarweb/web/[^/]+$ ]] || [[ "$path" =~ ^/trustpilot/business/[^/]+$ ]] || [[ "$path" =~ ^/trustpilot/business/[^/]+/reviews$ ]]; then : else # Check separately for exact, non-parameterized routes or reject. exit 2 fi ``` 3. Define an explicit allowed HTTP method for each route rather than allowing both GET and POST globally. The documented scrape and extract endpoints should accept POST, while the remaining catalog endpoints should accept GET. 4. Validate dynamic identifiers against their expected character sets and length limits where those constraints are known. 5. Add negative tests covering extra segments, including `/producthunt/product/id/unknown`, `/similarweb/web/domain/extra`, and `/trustpilot/business/slug/reviews/extra`. 6. Retain the fixed HTTPS origin and existing credential-handling protections.
