T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:818
- Finding
- Recipient Validation Sends an Unsolicited WhatsApp Message and Fails Open<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 818-846 **Vulnerability Type**: Validation with unintended external side effects and fail-open exception handling **Risk Level**: High ### Vulnerable Code ```python def is_registered_on_whatsapp(phone_digits: str, token: str, phone_id: str) -> bool: """ Check if number is a registered WhatsApp user. Returns False only on definitive error 131026 (not on WhatsApp). Returns True if successful, uncertain (auth error, etc.), or timeout. """ headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json" } data = { "messaging_product": "whatsapp", "to": phone_digits, "type": "text", "text": {"body": "_"} # minimal text to check } try: r = requests.post( f"https://graph.facebook.com/v21.0/{phone_id}/messages", headers=headers, json=data, timeout=10 ) if r.status_code == 200: return True # number is valid error_code = r.json().get("error", {}).get("code") if error_code == 131026: return False # NOT on WhatsApp return True # other errors — don't block except: return True # network error — don't block ``` ### Technical Analysis The function is represented as a recipient-validation helper, but it calls the `/messages` endpoint and attempts to deliver an actual `_` message. This is a state-changing messaging operation rather than a read-only validation request. It therefore discloses the supplied telephone number to Meta and can contact a recipient who has not consented to receiving the message. The function also catches every exception and returns `True`. Authentication failures, timeouts, malformed responses, rate limits, and programming errors are consequently treated as successful validation. Downstream code may then send further content to a recipient ...[truncated 906 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove message transmission from recipient-validation logic. - Perform E.164 syntax validation locally and use only an officially documented, consent-preserving verification mechanism. - Require recorded recipient opt-in before any state-changing messaging request. - Fail closed when verification is uncertain. - Catch specific exceptions such as timeout, connection, and JSON-decoding errors; return an explicit indeterminate result rather than `True`. - Separate `valid`, `invalid`, and `verification_failed` states so callers cannot confuse network failure with successful validation. - Add tests confirming that validation never invokes the message-sending endpoint. ]]>
