T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/send_sms.py:35
- Finding
- API Credentials and SMS Content Exposed in URL Query Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scripts/send_sms.py`, lines 35–45 **Vulnerability Type**: Sensitive information transmitted in URL query parameters **Risk Level**: Medium ### Vulnerable Code ```python params = { "api_username": username, "api_password": password, "method": "sendSMS", "did": args.did, "dst": args.dst, "message": args.message, "content_type": "json", } data = urllib.parse.urlencode(params) url = f"{API_URL}?{data}" ``` ### Technical Analysis The script includes the VoIP.ms API username, API password, source phone number, destination phone number, and complete SMS message in the query string of an HTTPS URL. HTTPS encrypts the request while it is in transit, so a passive network observer cannot ordinarily read these values. However, TLS does not prevent the complete URL from being recorded after decryption by the destination service, reverse proxies, application monitoring systems, debugging tools, or endpoint telemetry. URLs are generally more likely to be retained in logs than POST request bodies. Sending SMS content and credentials to VoIP.ms is necessary for the declared functionality. The vulnerability is the placement of that sensitive information in the URL rather than in an API-supported request body. No evidence was found that the data is sent to an unrelated endpoint. ### Attack Path 1. A user supplies a source DID, destination number, and SMS message and runs the script with VoIP.ms credentials in environment variables. 2. The script URL-encodes the credentials, phone numbers, and message into the request URL. 3. A VoIP.ms-side log, intermediary proxy, monitoring product, debugging trace, or endpoint telemetry system records the full URL. 4. An attacker or unauthorized operator obtains access to that retained URL. 5. The attacker reads the SMS content and phone numbers and extracts the reusable API credentials. 6. The attacker uses those credentials against the VoIP.ms API, subj ...[truncated 564 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Use an API-supported HTTPS POST request and place the parameters in the request body rather than the URL: ```python params = { "api_username": username, "api_password": password, "method": "sendSMS", "did": args.did, "dst": args.dst, "message": args.message, "content_type": "json", } data = urllib.parse.urlencode(params).encode("utf-8") req = urllib.request.Request( API_URL, data=data, headers={ "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "OpenClaw/1.0", }, method="POST", ) ``` 2. Confirm that the VoIP.ms API supports POST for this operation before deployment. 3. Never log the request URL, request body, credentials, or SMS message. 4. Ensure exception handling does not expose a request object or URL containing secrets. 5. Continue requiring a dedicated API sub-account restricted to SMS permissions. 6. Rotate credentials if URLs containing credentials may already have been logged. 7. Apply appropriate retention and access controls to terminal output and API response logs. ]]>
