T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/meta_ads_agent.py:238
- Finding
- Mutation approval is not cryptographically or semantically bound to the requested operation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/meta_ads_agent.py:238-260`, with affected call sites at `scripts/meta_ads_agent.py:329-338` and `scripts/meta_ads_agent.py:414-423` **Vulnerability Type**: Weak authorization validation and reusable approval **Risk Level**: High ### Vulnerable Code ```python def approval_is_specific(text: Optional[str]) -> bool: if not text: return False compact = " ".join(text.strip().split()) return len(compact) >= 25 and compact.lower() not in GENERIC_APPROVALS def safety_problem(cls: Dict[str, Any], approved: Optional[str], allow_active: bool, allow_budget: bool, allow_destructive: bool, allow_unknown: bool) -> Optional[str]: if cls.get("secret_arg_signals"): return "Do not pass access tokens or secrets as CLI arguments. Put credentials in environment variables or official auth storage." if cls["risk"] == "non_meta": return "Refusing to run non-`meta ads` command through this guard." if cls["risk"] == "unknown" and not allow_unknown: return "Unknown CLI action. Check `meta ads <resource> <action> --help`; use --allow-unknown only after review." if cls["requires_approval"] and not approval_is_specific(approved): return "Write or unknown-risk command requires --approved with specific user approval, not a generic yes/ok." if cls["requires_allow_active"] and not allow_active: return "Activation requires --allow-active plus specific approval." if cls["requires_allow_budget"] and not allow_budget: return "Budget/bid/spend change requires --allow-budget plus specific approval." if cls["requires_allow_destructive"] and not allow_destructive: return "Destructive command requires --allow-destructive plus specific approval." return None ``` The direct command execution path accepts either command-line or reusable environment-based approval: ```python def cmd_run(args: argparse.Namespace) -> int: raw = strip ...[truncated 4246 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace free-form approval validation with a structured approval object containing: - Ad account ID - Resource type and action - Exact object ID - Exact fields and proposed values - Risk class - Issuance and expiration times - A unique nonce 2. Normalize the exact command and calculate a digest over its security-relevant arguments. Require the approved command digest to match the command being executed. 3. Make approvals single-use. Record consumed nonces or approval identifiers and reject replay attempts. 4. Remove or disable `META_ADS_AGENT_APPROVED` for write operations. If environment-based approval must remain, require a short expiration, one command digest, and one account scope. 5. Validate high-risk details explicitly. For example, budget approval should match the exact campaign ID, account ID, budget type, currency or minor-unit interpretation, and new amount. 6. Bind plan approval to the complete immutable plan digest. Do not apply one unstructured sentence to changed or additional plan steps. 7. Add tests proving that approval for one account, resource, object, value, or action cannot authorize a different operation. ]]>
