Back to skill

Security audit

Voipms Sms

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to do what it says, but it handles SMS data and reusable VoIP.ms credentials in a way that can expose them through request URL logs.

Review before installing. Use only a dedicated VoIP.ms API sub-account limited to SMS, avoid sending highly sensitive messages through this tool, treat terminal output as sensitive, and prefer an implementation that sends credentials and message parameters in a POST body if the VoIP.ms API supports it. Rotate credentials if full request URLs may have been logged.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

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. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get_sms.py:54
Finding
API Credentials Exposed in SMS Retrieval URL Query Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scripts/get_sms.py`, lines 54–66 **Vulnerability Type**: Sensitive information transmitted in URL query parameters **Risk Level**: Medium ### Vulnerable Code ```python params = { "api_username": username, "api_password": password, "method": "getSMS", "from": date_from, "to": date_to, "content_type": "json", } if args.did: params["did"] = args.did data = urllib.parse.urlencode(params) url = f"{API_URL}?{data}" ``` ### Technical Analysis The retrieval script embeds the VoIP.ms API username and password in an HTTPS URL query string. The URL may additionally identify a specific DID and the requested message-history date range. Although HTTPS protects the request from ordinary passive interception in transit, query strings may be retained by the API service, reverse proxies, debugging facilities, monitoring products, or local endpoint telemetry. Anyone who obtains such a URL can recover the API credentials. The request is sent only to the declared VoIP.ms API endpoint, and transmitting authentication information is necessary to retrieve SMS records. The identified weakness is the use of query parameters for reusable credentials. The script also prints the complete API response to standard output; this is consistent with its declared retrieval function, but that output should be treated as sensitive because it may contain SMS records. ### Attack Path 1. A user runs the retrieval script with VoIP.ms credentials in environment variables. 2. The script inserts the username and password into the request URL. 3. An API-side system, intermediary proxy, monitoring product, debugging trace, or endpoint telemetry system records the URL. 4. An attacker or unauthorized operator gains access to that retained URL. 5. The attacker extracts the reusable VoIP.ms credentials. 6. The attacker queries SMS history or invokes other API methods permitted for the account. 7. If the compromised accou ...[truncated 791 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use an API-supported HTTPS POST request and move authentication and filter parameters into the request body: ```python params = { "api_username": username, "api_password": password, "method": "getSMS", "from": date_from, "to": date_to, "content_type": "json", } if args.did: params["did"] = args.did 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. Verify that VoIP.ms supports POST for `getSMS` before making the change. 3. Do not log complete request URLs, bodies, credentials, or unredacted API responses. 4. Retain the documented requirement for a dedicated VoIP.ms API account with only SMS permissions. 5. Consider requiring an explicit DID by default where operationally feasible, reducing the amount of data returned by accidental or unauthorized use. 6. Apply access controls and retention limits to console output because retrieved SMS records are sensitive. 7. Rotate any credentials that may have appeared in historical URL logs. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Tainted flow: 'req' from os.environ.get (line 69, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
req = urllib.request.Request(url, headers={'User-Agent': 'OpenClaw/1.0'})

    try:
        with urllib.request.urlopen(req) as response:
            body = response.read().decode("utf-8")
    except Exception as exc:
        print(f"Error: API request failed: {exc}", file=sys.stderr)
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'req' from os.environ.get (line 51, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
req = urllib.request.Request(url, headers={'User-Agent': 'OpenClaw/1.0'})

    try:
        with urllib.request.urlopen(req) as response:
            body = response.read().decode("utf-8")
    except Exception as exc:
        print(f"Error: API request failed: {exc}", file=sys.stderr)
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The code clearly implements SMS retrieval only: it parses optional DID and day-range arguments, loads VoIP.ms API credentials from environment variables, calls the VoIP.ms `getSMS` method, and outputs the result. This aligns with the retrieval portion of the description and is consistent with the stated lack of Bitwarden dependency. However, the declared purpose says the skill supports both sending and retrieving SMS messages, while this code chunk shows only retrieval behavior and no sending functionality. That is a material description-behavior mismatch for the supplied code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The code is consistent with part of the description: it uses the VoIP.ms API and has no Bitwarden dependency. However, the declared purpose says the skill supports both sending and retrieving SMS messages, while this code chunk only sends SMS messages using the sendSMS API method. No retrieval functionality is present in the provided code. That is a material description-to-behavior mismatch for the supplied chunk, even though the sending portion is accurately represented.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documentation instructs use of environment variables for API credentials and describes network-capable scripts, but it does not declare any explicit tool scope or permissions. In agent ecosystems, missing scope declarations can allow broader-than-expected access to secrets and outbound connectivity, reducing transparency and making misuse harder to constrain or audit.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This manifest describes sending and retrieving SMS via the VoIP.ms API and declares required username/password environment variables, but it provides no warning or disclosure about handling sensitive credentials or transmitting user message data to a third-party service. For a manifest/description file, the skill description should clearly warn about privacy and credential implications of these behaviors.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script places API username and password directly in the request URL query string. Even though the request uses HTTPS, URLs are commonly exposed in client logs, proxy logs, browser/history equivalents, debugging output, monitoring systems, and upstream infrastructure, which can leak long-lived credentials.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script places API username, API password, destination number, and SMS message in the request URL query string. Even though the request uses HTTPS, query strings are more likely to be exposed through proxy logs, debugging tools, browser/history equivalents, upstream infrastructure, or exception telemetry, causing credential leakage and disclosure of message contents.

Static analysis

No suspicious patterns detected.