Back to skill

Security audit

Android SMS Gateway

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its SMS gateway purpose, but it needs Review because it handles sensitive SMS data and credentials with weak transport and webhook safeguards.

Install only if you are comfortable giving the agent scripts access to send SMS, read received SMS, and use gateway credentials. Prefer HTTPS, VPN, or a private trusted network; avoid public webhook collectors for real SMS traffic; use dry-run before bulk sends; protect config files; and delete test webhooks after use.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/receive_sms.sh:152
Finding
SMS content and gateway credentials can be transmitted over plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/receive_sms.sh:152-171` **Vulnerability Type**: Cleartext transmission of sensitive information **Risk Level**: High The same insecure transport pattern also occurs in the sending, bulk-send, status-check, and webhook-management scripts. The documentation recommends gateway URLs such as `http://192.168.1.100:8080`. ### Vulnerable Code ```bash # Fetch received messages fetch_messages() { local url="${GATEWAY_URL}/api/v1/messages/received" local auth_header="Authorization: Bearer ${API_TOKEN}" local query_params="limit=${LIMIT}" if [[ -n "$SINCE" ]]; then query_params="${query_params}&since=${SINCE}" fi log_verbose "GET ${url}?${query_params}" local response local http_code response=$(curl -s -w "\n%{http_code}" \ -X GET "${url}?${query_params}" \ -H "$auth_header" \ -H "Accept: application/json" \ --max-time "$TIMEOUT" \ 2>/dev/null) || { log_error "Failed to connect to gateway" exit 1 } ``` Related affected locations include: - `scripts/send_sms.sh:191-221` - `scripts/bulk_sms.sh:239-258` - `scripts/check_status.sh:139-155` - `scripts/send_sms_capcom6.sh:238-266` - `scripts/bulk_sms_capcom6.sh:281-320,333-353` - `scripts/check_status_capcom6.sh:172-193` - `scripts/register_webhook_capcom6.sh:231-250` - `SKILL.md:50,70,104-107,130,139` - `references/api_reference.md:13,37-38,61-66,106-107,222-226,269-274` - `references/capcom6_reference.md:16-18,29-48` ### Technical Analysis The scripts accept a user-configured gateway URL without enforcing HTTPS. The documented default local configuration uses HTTP. Requests then attach either a bearer token or Basic Authentication credentials and, depending on the operation, transmit recipient numbers, message bodies, received SMS records, and device-status information. Bearer tokens and Basic Authentication credentials provide no trans ...[truncated 1685 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject plaintext gateway URLs by default: - Require URLs beginning with `https://`. - Permit HTTP only through an explicit option such as `--allow-insecure-local-http`. - Display a prominent warning whenever the insecure override is used. 2. Restrict curl to the intended protocol and preserve certificate validation: ```bash curl --proto '=https' --tlsv1.2 \ --fail-with-body \ --connect-timeout 5 \ --max-time "$TIMEOUT" \ ... ``` 3. For local Android gateways that do not support TLS: - Place the gateway behind a TLS-enabled reverse proxy. - Use a trusted VPN or mutually authenticated tunnel. - Restrict the gateway port to the OpenClaw host with firewall rules. - Avoid port forwarding the plaintext service. 4. Consider certificate or private-CA pinning for production deployments. Do not recommend `curl --insecure`. 5. Avoid credentials in command-line arguments because they may appear in process listings or shell history. Prefer a permission-restricted configuration file, a protected credential helper, or environment injection from a secret manager. 6. Document that SMS can contain highly sensitive information and that plaintext HTTP is unsuitable even on many local networks. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/send_sms.sh:191
Finding
User-controlled values are interpolated into JSON without encoding<![CDATA[ ## Vulnerability Details **File Location**: `scripts/send_sms.sh:191-221` **Vulnerability Type**: JSON injection and malformed request construction **Risk Level**: Medium Equivalent manual JSON construction occurs in: - `scripts/send_sms_capcom6.sh:243-248` - `scripts/bulk_sms.sh:243-248` - `scripts/bulk_sms_capcom6.sh:274-290,334-339` - `scripts/register_webhook_capcom6.sh:232-234` ### Vulnerable Code ```bash # Send SMS via SMS Gateway API (itsmeichigo/SMSGateway) send_sms_gateway_api() { local to="$1" local message="$2" local sim_slot="$3" local url="${GATEWAY_URL}/api/v1/send" local auth_header="Authorization: Bearer ${API_TOKEN}" # Build JSON payload local payload="{\"phone\":\"${to}\",\"message\":\"${message}\"" if [[ -n "$sim_slot" ]]; then payload="${payload},\"sim\":${sim_slot}" fi payload="${payload}}" log_verbose "POST $url" log_verbose "Payload: $payload" if [[ "${DRY_RUN:-0}" == "1" ]]; then echo "[DRY RUN] Would send:" echo " URL: $url" echo " To: $to" echo " Message: $message" echo " Payload: $payload" return 0 fi # Send request local response local http_code response=$(curl -s -w "\n%{http_code}" \ -X POST "$url" \ -H "$auth_header" \ -H "Content-Type: application/json" \ -d "$payload" \ --max-time "$TIMEOUT" \ 2>/dev/null) || { log_error "Failed to connect to gateway at $GATEWAY_URL" exit 1 } ``` ### Technical Analysis The script inserts the recipient, message, and SIM-slot values directly into a JSON string. It does not apply JSON escaping to quotation marks, backslashes, newlines, control characters, or other special values. For example, a message containing a quotation mark can terminate the intended JSON string. A crafted value can then introduce additional properties if the receiving API accepts the ...[truncated 1733 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Generate every request body with a real JSON encoder rather than string concatenation. For example: ```bash if [[ -n "$sim_slot" ]]; then [[ "$sim_slot" =~ ^[12]$ ]] || { log_error "SIM slot must be 1 or 2" exit 1 } payload=$(jq -n \ --arg phone "$to" \ --arg message "$message" \ --argjson sim "$sim_slot" \ '{phone: $phone, message: $message, sim: $sim}') else payload=$(jq -n \ --arg phone "$to" \ --arg message "$message" \ '{phone: $phone, message: $message}') fi ``` Apply the same pattern to all capcom6 bulk and webhook payloads: - Use `jq --arg` for strings. - Use `jq --argjson` only after strict numeric or Boolean validation. - Build recipient arrays with `jq`, rather than concatenating quoted values. - Allowlist webhook event names. - Validate SIM slots as exactly `1` or `2`. - Validate timeout and delay arguments as bounded non-negative integers. - Add tests covering quotes, backslashes, Unicode, tabs, and multiline SMS content. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/register_webhook_capcom6.sh:74
Finding
Documentation recommends forwarding incoming SMS to a public webhook service<![CDATA[ ## Vulnerability Details **File Location**: `scripts/register_webhook_capcom6.sh:74-80` **Vulnerability Type**: Unsafe external disclosure guidance for sensitive SMS data **Risk Level**: Medium Webhook registration is implemented at `scripts/register_webhook_capcom6.sh:224-267`, and the documented webhook payload in `references/capcom6_reference.md:50-60` contains the complete received message and sender phone number. ### Vulnerable Code ```text # Cloud mode $0 --mode cloud --url "https://your-server.com/webhook" Notes: - Webhook URL must be publicly accessible (HTTPS recommended) - For testing, use https://webhook.site to get a temporary URL - Webhooks are transmitted directly from the device - Local and Cloud mode webhooks are independent ``` The registration logic is: ```bash # Register webhook register_webhook() { if [[ -z "$WEBHOOK_URL" ]]; then log_error "Webhook URL required for registration" exit 1 fi local url="${GATEWAY_URL}/webhooks" local webhook_id="${WEBHOOK_ID:-webhook_$(date +%s)_$$}" local payload="{\"id\":\"${webhook_id}\",\"url\":\"${WEBHOOK_URL}\",\"event\":\"${WEBHOOK_EVENT}\"}" log_info "Registering webhook..." log_verbose "POST $url" log_verbose "Payload: $payload" local response local http_code response=$(curl -s -w "\n%{http_code}" \ -X POST "$url" \ -u "${GATEWAY_USER}:${GATEWAY_PASS}" \ -H "Content-Type: application/json" \ -d "$payload" \ --max-time "$TIMEOUT" \ 2>/dev/null) || { log_error "Failed to connect to gateway" exit 1 } http_code=$(echo "$response" | tail -n1) local body=$(echo "$response" | sed '$d') log_verbose "HTTP $http_code" if [[ "$http_code" == "200" || "$http_code" == "201" ]]; then log_info "✓ Webhook registered successfully" echo "" echo " Webhook ID: $webhook_id" echo " U ...[truncated 2357 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the recommendation to use a public webhook collection service, or explicitly state that it must never be used with real SMS traffic. 2. Recommend a self-hosted HTTPS endpoint under the user's control. 3. Reject webhook URLs that do not use HTTPS, except for an explicit local-development override. 4. Add a confirmation prompt before registering third-party domains. The prompt should state that full SMS content and sender metadata will be disclosed. 5. Support webhook authentication: - A per-webhook bearer secret - HMAC signatures with timestamp and replay protection - Mutual TLS where supported 6. Provide immediate cleanup instructions after registration: ```bash ./scripts/register_webhook_capcom6.sh --delete "$WEBHOOK_ID" ``` 7. If supported by the gateway, add automatic expiry or a one-shot testing mode. 8. Avoid claiming that webhooks must always be publicly accessible; private servers reachable over a VPN or controlled private network are preferable. 9. Document data retention, logging, redaction, and access-control requirements for any webhook receiver. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (38)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The code clearly implements outbound SMS sending only. It validates recipients, loads gateway credentials, and posts message payloads to a /message endpoint for either single or multi-recipient sends. There is no code for receiving SMS, polling inboxes, webhook handling, message retrieval, or any other inbound SMS functionality. That is a material mismatch because the declared description says the skill is for sending/receiving SMS. Additionally, while the description suggests broader support for popular SMS gateway apps, this code is tailored to a specific capcom6 API structure and endpoint. The primary purpose still falls within self-hosted Android SMS sending, so the mismatch is not total, but the undeclared absence of receive capability makes the description inaccurate.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The script’s primary function aligns substantially with SMS sending via an Android SMS gateway over HTTP. However, the declared description says the skill supports both sending and receiving SMS, while the provided code chunk only implements outbound sending. Additionally, the description emphasizes self-hosted use without third-party providers, but the code includes a cloud mode that hardcodes a third-party service endpoint. These are material description-to-behavior gaps, even though the core sending behavior is broadly consistent.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
---

#### DELETE /messages/:id

Delete a message from history.
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

YARA rule 'offensive_tool_references': References to well-known offensive security tools [hacktools]

High
Category
YARA Match
Content
eway on LAN
2. **Strong tokens:** 32+ character random strings
3. **HTTPS:** Use reverse proxy if exposing externally
4. **Firewall:** Restrict access to gateway port
5. **Monitoring:** Log all API requests

---

## Troubleshooting

### Connection Refused

```bash
# Check phone is reachable
ping PHONE_IP

# Check app is running
# On phone: Open SMS Gateway app, verify server started

# Check port
nmap -p 8080 PHONE_IP
```

### Authentication Failed

```bash
# Verify token matches app settings
curl -v http://PHONE_IP:8080/api/v1/status \
  -H "Authorization: Bearer YOUR_TOKEN"

# Check for typos, trailing spaces
```

### Message Not Delivered

1. Check phone has signal
2. Verify SMS plan/credit
3. Check app logs for errors
4. Verify recipient number format
5. Check carrier spam filters

---

## Alternative Apps

If the recommended app doesn't work for your device, try:

| App | GitHub | Notes |
|-----|--------|-------|
| SMS Gateway API | itsmeichigo/SMSGateway | ⭐ Recommended, active
Confidence
70% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documents shell-script execution but does not declare any explicit tool scope or allowed-tools boundary. In an agent environment, this increases the chance the skill will be executed with broader shell capability than users expect, which can enable unintended command execution or unsafe file/network access.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill handles highly sensitive communications data—phone numbers, message bodies, and potentially authentication codes—without prominent privacy and data-handling warnings. Users may expose personal or regulated data through SMS APIs and logs without understanding retention, transport, and disclosure risks.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation encourages placement of tokens, usernames, and passwords in environment variables and config files without strong warning about secret exposure. In practice, such secrets can leak through shell history, process inspection, misconfigured home-directory permissions, backups, or accidental commits.

Session Persistence

Medium
Category
Rogue Agent
Content
### Option 2: Config File

Create `~/.openclaw/sms-gateway.json`:

```json
{
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
export SMS_GATEWAY_URL="http://192.168.1.100:8080"  # Local server
# export SMS_GATEWAY_URL="https://api.sms-gate.app/3rdparty/v1"  # Cloud
export SMS_GATEWAY_USER="your-username"
export SMS_GATEWAY_PASS="your-password"
export SMS_GATEWAY_TIMEOUT="30"
Confidence
92% confidence
Finding
The skill explicitly supports a cloud API endpoint, which means SMS content, recipient numbers, and credentials may be transmitted to a third-party service outside the local network. In the context of a tool marketed as self-hosted and privacy-preserving, this increases the risk of unintended data disclosure and trust-boundary expansion.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
Webhook registration for incoming SMS can forward message content and sender metadata to an external server, but the documentation does not prominently warn users of that privacy and exfiltration risk. This is especially dangerous because incoming SMS may contain passwords, MFA codes, personal data, or incident-response information.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- **App:** SMS Gateway API (itsmeichigo/SMSGateway)
- **Phone:** Samsung Galaxy, IP: 192.168.1.100
- **Port:** 8080
- **Token:** Stored in ~/.openclaw/sms-gateway.json (chmod 600)
```

## API Reference
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
- **Strong tokens:** Use random API tokens (32+ chars)
- **Token rotation:** Rotate tokens periodically
- **File permissions:** `chmod 600 ~/.openclaw/sms-gateway.json`

### Rate Limiting
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# Cron job for daily security reminder
# crontab -e
0 9 * * * /path/to/send_sms.sh --to "+1234567890" --message "Daily security check: Review logs"
```
Confidence
85% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

External Transmission

Medium
Category
Data Exfiltration
Content
**Request:**
```bash
curl http://PHONE_IP:8080/api/v1/status \
  -H "Authorization: Bearer YOUR_TOKEN"
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
**Request:**
```bash
curl -X GET "http://PHONE_IP:8080/api/v1/messages/sent?limit=10" \
  -H "Authorization: Bearer YOUR_TOKEN"
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This markdown file documents a DELETE endpoint that removes message history, but it does not include any warning that the operation is destructive or potentially irreversible. For markdown files, safety-impacting behaviors that affect user data should be explicitly disclosed.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The webhook section tells users to configure an external callback URL and shows SMS metadata being transmitted, but it does not warn that message identifiers, phone numbers, delivery status, and timing data will leave the local gateway environment. In a security-focused context, omission of this warning can lead to inadvertent disclosure of sensitive communications metadata to third-party infrastructure.

External Transmission

Medium
Category
Data Exfiltration
Content
### Send SMS
```bash
curl -X POST http://IP:8080/message \
  -u username:password \
  -H "Content-Type: application/json" \
  -d '{
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
This shell script performs a safety-sensitive external action by sending SMS messages to multiple recipients over the network, but the non-dry-run path proceeds directly from a brief status log to transmission. Although the script documents usage and provides a dry-run mode, it does not include an explicit confirmation prompt or warning immediately before the irreversible send operation.

External Transmission

Medium
Category
Data Exfiltration
Content
local response
    local http_code
    
    response=$(curl -s -w "\n%{http_code}" \
        -X POST "$url" \
        -u "${GATEWAY_USER}:${GATEWAY_PASS}" \
        -H "Content-Type: application/json" \
Confidence
84% confidence
Finding
This code transmits user-supplied message content and recipient phone numbers to an external SMS gateway over HTTP(S), which is the intended function of the skill but still constitutes real exfiltration of potentially sensitive data. In this skill's context, the danger is elevated because security teams may send incident-related alerts, phone lists, or sensitive operational messages, and the script does not restrict destinations or validate the trust boundary of the configured gateway.

External Transmission

Medium
Category
Data Exfiltration
Content
local response
    local http_code
    
    response=$(curl -s -w "\n%{http_code}" \
        -X POST "$url" \
        -u "${GATEWAY_USER}:${GATEWAY_PASS}" \
        -H "Content-Type: application/json" \
Confidence
84% confidence
Finding
Like the multi-recipient path, the single-recipient fallback sends message text and phone numbers to an external gateway, creating an outbound data transmission channel. Although this is expected behavior for an SMS gateway script, it is still security-relevant because misuse, misconfiguration, or attacker-controlled inputs could cause disclosure of sensitive content or abuse of the SMS service.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script can send real SMS messages to many recipients immediately once invoked, with no confirmation prompt, recipient summary acknowledgement, or safety interlock beyond an optional dry-run flag. In a security-team automation context, this increases the risk of accidental mass messaging, operational disruption, and unintended disclosure to external phone numbers if inputs or invocation parameters are wrong.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The script reads username and password from environment variables or config and then sends them via curl basic authentication, but there is no user-facing warning in comments, help text, or runtime output about credential use or transmission. Because this is a code file handling sensitive credentials and making a network request, the lack of disclosure matches the missing-warning criteria.

External Transmission

Medium
Category
Data Exfiltration
Content
# Set default URL based on mode
    if [[ "$SERVER_MODE" == "cloud" ]]; then
        GATEWAY_URL="https://api.sms-gate.app/3rdparty/v1"
        log_verbose "Using cloud server mode"
    fi
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# Set default URL based on mode
    if [[ "$SERVER_MODE" == "cloud" ]]; then
        GATEWAY_URL="https://api.sms-gate.app/3rdparty/v1"
        log_verbose "Using cloud server mode"
    fi
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.