T09 · Insecure Skill Coding Practices
Error
- Location
- scripts.md:114
- Finding
- Campaign Mutation Scripts Bypass the Promised Confirmation Gate<![CDATA[ ## Vulnerability Details **File Location**: `scripts.md`, lines 114-142 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code ```bash # Environment variables accessed: ASA_ACCESS_TOKEN, ASA_ORG_ID # External endpoints called: https://api.searchads.apple.com/api/v5/campaigns # Local files written: none : "${ASA_ACCESS_TOKEN:?Set ASA_ACCESS_TOKEN}" : "${ASA_ORG_ID:?Set ASA_ORG_ID}" # Arguments NAME="${1:?Usage: $0 <name> <adam_id> <country> <daily_budget>}" ADAM_ID="${2:?Missing adam_id}" COUNTRY="${3:?Missing country}" DAILY_BUDGET="${4:?Missing daily_budget}" curl -s -X POST "https://api.searchads.apple.com/api/v5/campaigns" \ -H "Authorization: Bearer $ASA_ACCESS_TOKEN" \ -H "X-AP-Context: orgId=$ASA_ORG_ID" \ -H "Content-Type: application/json" \ -d '{ "name": "'"$NAME"'", "adamId": '"$ADAM_ID"', "countriesOrRegions": ["'"$COUNTRY"'"], "budgetAmount": {"amount": "10000", "currency": "USD"}, "dailyBudgetAmount": {"amount": "'"$DAILY_BUDGET"'", "currency": "USD"}, "supplySources": ["APPSTORE_SEARCH_RESULTS"], "billingEvent": "TAPS", "status": "ENABLED" }' | jq ``` Equivalent immediate-mutation behavior also appears in the pause, add-keyword, and add-negative scripts at `scripts.md:153-168`, `scripts.md:181-203`, and `scripts.md:216-235`. ### Technical Analysis The Skill states that every mutation script respects `confirm_before_push`, and `SKILL.md` defines that setting as the approval gate for changes affecting bids, budgets, campaign status, and keywords. However, the mutation scripts neither read `config.yaml` nor inspect `confirm_before_push`. They also do not display a proposed change or prompt the operator before sending the authenticated request. The campaign creation example is particularly consequential because it creates the campaign with `"status": "ENABLED"`. Once invoked with valid credentials, the script immediately sends the request to Ap ...[truncated 1288 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Implement a shared confirmation function used by every mutation script. - Read `confirm_before_push` from the documented configuration file and default to `true` if the file or setting is absent. - Before sending a request, print the target organization, endpoint, resource identifiers, and exact normalized payload. - Require an explicit approval response such as `yes`; reject empty input and all other responses. - For non-interactive use, require a deliberate option such as `--yes` or `--unattended`, rather than silently detecting a non-interactive terminal. - Keep destructive operations such as deletion subject to confirmation even when unattended changes are otherwise enabled. - Consider creating new campaigns in a paused state by default and requiring a separate confirmation to enable them. - Add tests that mock `curl` and verify no mutation request is sent before approval. ]]>
