T09 · Insecure Skill Coding Practices
Error
- Location
- EXAMPLES.md:499
- Finding
- Workflow Execution Is Gated by Transport Success Instead of the Authorization Decision## Vulnerability Details **File Location**: `EXAMPLES.md`, lines 499-508 **Vulnerability Type**: Improper authorization-result validation **Risk Level**: High **Vulnerable code:** ```bash # 1. Check permissions curl -X POST /api/v1/permissions/check -d '{...}' # 2. If allowed, execute operation if [ $? -eq 0 ]; then curl -X POST /api/v1/workflows/execute -d '{...}' fi ``` ### Technical Analysis The example uses the exit status of `curl` as if it represented the permission decision. By default, `curl` returns a successful exit status when it successfully completes the HTTP exchange, even if the server returns an authorization denial such as HTTP 401 or 403. It can also return zero when a permission endpoint returns HTTP 200 with an application-level result such as `"allowed": false`. The script neither enables `curl --fail`/`--fail-with-body` nor parses and validates the response body's authorization field. Consequently, a completed permission-check request may satisfy `[ $? -eq 0 ]` regardless of whether access was granted. The relative URLs shown in this conceptual example require a configured host or correction before execution. Once used with a valid API base URL, however, the authorization-control error remains. ### Attack Path 1. An attacker or unauthorized user requests a sensitive cross-system workflow. 2. The client sends the pre-flight request to the permission-check endpoint. 3. The endpoint returns a normal HTTP response containing a denial, or returns an HTTP authorization error without causing `curl` to fail. 4. `curl` exits with status zero because the HTTP exchange completed. 5. The shell condition treats the transport-level success as an authorization grant. 6. The client sends the workflow-execution request. 7. If the workflow endpoint relies on this client-side pre-flight check instead of independently enforcing authorization, the unauthorized workflow executes. ### Impact Assessment ...[truncated 771 chars]
- Remediation
- ## Remediation Suggestions - Do not use process exit status alone as an authorization decision. - Use `curl --fail-with-body` so HTTP error responses produce a nonzero status. - Parse the JSON response and require the authorization field to be exactly `true` before proceeding. - Fail closed when the response is missing, malformed, timed out, or ambiguous. - Require the workflow endpoint to perform its own server-side authorization check. Client-side pre-flight checks must never be the security boundary. - Consider issuing a short-lived, signed authorization-decision token bound to the user, action, resource, workflow, and expiration time. Validate that token at execution. - Add tests covering HTTP 401, HTTP 403, HTTP 500, malformed JSON, timeouts, and HTTP 200 responses containing `"allowed": false`. A safer illustrative pattern is: ```bash response="$(curl --fail-with-body -sS \ -X POST "$API_BASE/api/v1/permissions/check" \ -H "Content-Type: application/json" \ -d '{...}')" || exit 1 allowed="$(printf '%s' "$response" | jq -er '.allowed')" [ "$allowed" = "true" ] || exit 1 curl --fail-with-body -sS \ -X POST "$API_BASE/api/v1/workflows/execute" \ -d '{...}' ```
