T09 · Insecure Skill Coding Practices
- Location
scripts/gr_api.py:25- Finding
State-Changing API Operations Bypass the Documented Confirmation Gate
- Content
View full analysis
Vulnerability Details
File Location:
scripts/gr_api.py, lines 25–70
Vulnerability Type: Missing authorization and confirmation enforcement for destructive API operations
Risk Level: HighRelevant code:
python parser.add_argument("method", choices=["GET", "POST", "PUT", "PATCH", "DELETE"]) parser.add_argument("path", help="API path, e.g. /accounts/{account_slug}/advocates") parser.add_argument("--base-url", default=os.environ.get("GR_API_BASE_URL", "https://api.geniusreferrals.com")) parser.add_argument("--token", default=os.environ.get("GR_API_TOKEN")) parser.add_argument("--account", default=os.environ.get("GR_ACCOUNT_SLUG")) parser.add_argument("--path-param", action="append", default=[], help="Path replacement as key=value") parser.add_argument("--query", action="append", default=[], help="Query param as key=value") parser.add_argument("--json", default=None, help="JSON request body") args = parser.parse_args() if not args.token: raise SystemExit("Missing GR_API_TOKEN or --token") path_params = parse_pairs(args.path_param) if args.account: path_params.setdefault("account_slug", args.account) path = args.path for key, value in path_params.items(): path = path.replace("{" + key + "}", urllib.parse.quote(value, safe="")) if "{" in path or "}" in path: raise SystemExit(f"Unresolved path parameter in: {path}") query = urllib.parse.urlencode(parse_pairs(args.query)) url = args.base_url.rstrip("/") + "/" + path.lstrip("/") if query: url += "?" + query body = None headers = { "Accept": "application/json", "X-Auth-Token": args.token, } if args.json is not None: try: json.loads(args.json) except json.JSONDecodeError as error: raise SystemExit(f"Invalid JSON request body: {error.msg} at position {error.pos}") from None body = args.json.encode("utf-8") headers["Content-Type"] = "application/json" req ...[truncated 2486 chars]- Remediation
View remediation
Remediation Suggestions
- Make the helper read-only by default and reject all non-
GETmethods unless a separate mutation mode is explicitly enabled. - Implement a real dry-run mode that emits the normalized method, destination, account, endpoint, payload keys, expected impact, and rollback plan without sending a request.
- Require a non-optional confirmation artifact for every mutation. Bind it cryptographically or structurally to the exact normalized method, base URL, account, path, query, and request-body digest so it cannot authorize a different operation.
- Add a stronger confirmation tier for
DELETE, forced bonuses, payout actions, and redemption updates. - Require the production environment and account slug to be explicitly identified for mutations instead of relying only on implicit environment defaults.
- Enforce authentication testing before account-scoped changes, as required by
SKILL.md. - Consider endpoint allowlists and operation-specific validation rather than permitting arbitrary paths for state-changing methods.
- Keep authorization enforcement inside the executable helper so direct invocation cannot bypass policy stated only in documentation.
- Make the helper read-only by default and reject all non-
