Back to skill

Security audit

SMS Gateway

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its SMS purpose, but its setup instructions include running an unpinned remote installer as root, which warrants review before installation.

Review the installer before using this skill. Prefer a pinned release or verified checksum/signature instead of running the README curl-to-sudo commands, keep the API key outside shared or synced workspaces where possible, use HTTPS for any non-local gateway, and remember that checking messages prints SMS contents and marks unread messages as read.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
README.md:20
Finding
Unpinned Remote Installation Script Executed with Root Privileges## Vulnerability Details **File Location**: `README.md`, lines 20-28 **Vulnerability Type**: Unverified remote payload retrieval and privileged execution **Risk Level**: Critical **Complete vulnerable code snippet**: ```bash curl -fsSL https://raw.githubusercontent.com/mattboston/sms-gateway/main/install.sh | sudo bash ``` ```bash curl -fsSL -o install.sh https://raw.githubusercontent.com/mattboston/sms-gateway/main/install.sh chmod +x install.sh sudo ./install.sh ``` ### Technical Analysis The documented installation procedures download `install.sh` from the mutable `main` branch of an external GitHub repository and execute it with `sudo`. Neither procedure pins the payload to an immutable commit or release, and neither verifies a cryptographic checksum or signature. The first procedure pipes the network response directly into a root shell, preventing meaningful inspection before execution. The second procedure separates download and execution but still recommends running the unverified file as root. Because the remote installer is not included in the audited artifact, its effective behavior cannot be determined from this package and can change after review. Running an installer as root may be necessary for narrowly defined operations such as installing a system service or configuring device access. However, granting unrestricted root shell execution to mutable, unverified remote content exceeds the minimum safely verifiable privilege required by the OpenClaw Skill itself. ### Attack Path 1. An attacker compromises the repository owner’s account, repository, release process, or another component capable of modifying the `main` branch. 2. The attacker replaces or modifies `install.sh` with malicious shell commands. 3. A user follows the installation instructions in `README.md`. 4. `curl` retrieves the attacker-controlled version without integrity or authenticity verification beyond transport security. 5. `sudo ...[truncated 834 chars]
Remediation
## Remediation Suggestions 1. Remove the pipe-to-shell installation command. 2. Publish the installer and binary as versioned release artifacts rather than retrieving them from a mutable branch. 3. Pin downloads to an immutable release version or commit identifier. 4. Publish a SHA-256 checksum and require users to verify it before execution. 5. Prefer cryptographic release signatures with verification against a documented maintainer key. 6. Instruct users to inspect the downloaded installer before granting privileges. 7. Split privileged and unprivileged installation steps. Use `sudo` only for narrowly scoped operations that require it, such as copying a reviewed binary or creating a systemd unit. 8. Avoid allowing the installer to run an unrestricted root shell where dedicated package-management or service-management commands can accomplish the task. 9. Document the files, users, groups, device permissions, and services that installation will create or modify.

T09 · Insecure Skill Coding Practices

Warning
Location
config.sh:5
Finding
API Credential and SMS Data Can Be Transmitted over Plaintext HTTP## Vulnerability Details **File Locations**: `config.sh`, line 5; `send_sms.sh`, lines 46-50; `receive_sms.sh`, lines 35-39 and 65-68 **Vulnerability Type**: Plaintext transmission of credentials and sensitive SMS data **Risk Level**: Medium **Complete vulnerable code snippets**: `config.sh`, line 5: ```bash SMS_GATEWAY_URL="${SMS_GATEWAY_URL:-http://localhost:5174}" ``` `send_sms.sh`, lines 46-50: ```bash RESPONSE=$(curl -s -w "\n%{http_code}" \ -X POST "${SMS_GATEWAY_URL}/api/v1/sms/send" \ -H "X-API-Key: ${SMS_GATEWAY_API_KEY}" \ -H "Content-Type: application/json" \ -d "$(jq -n --arg to "${TO}" --arg body "${BODY}" '{to: $to, body: $body}')") ``` `receive_sms.sh`, lines 35-39: ```bash RESPONSE=$(curl -s -w "\n%{http_code}" \ -X GET "${SMS_GATEWAY_URL}/api/v1/sms/inbox${QUERY}" \ -H "X-API-Key: ${SMS_GATEWAY_API_KEY}" \ -H "Content-Type: application/json") ``` `receive_sms.sh`, lines 65-68: ```bash curl -s -X PUT "${SMS_GATEWAY_URL}/api/v1/sms/${ID}/read" \ -H "X-API-Key: ${SMS_GATEWAY_API_KEY}" \ -H "Content-Type: application/json" > /dev/null ``` ### Technical Analysis The default URL uses plaintext HTTP. When it remains limited to the local loopback interface, exposure to network interception is substantially reduced and this behavior is consistent with communicating with a self-hosted local gateway. However, `SMS_GATEWAY_URL` is configurable, and the scripts do not reject a non-loopback HTTP destination or require TLS for remote connections. Every request places `SMS_GATEWAY_API_KEY` in the `X-API-Key` header. Sending an SMS additionally transmits the recipient number and message body, while inbox retrieval returns sender numbers, message contents, timestamps, statuses, and identifiers. Consequently, configuring a remote gateway using `http://` sends authentication material and private communications without transport encryption. The static pre-scan warning fo ...[truncated 1453 chars]
Remediation
## Remediation Suggestions 1. Permit plaintext HTTP only when the resolved destination is an explicitly approved loopback address such as `127.0.0.1` or `::1`. 2. Reject non-loopback `http://` values and require `https://` for remote gateway connections. 3. Validate TLS certificates and do not introduce options such as `curl --insecure`. 4. Document secure reverse-proxy or native TLS configuration for remote deployments. 5. Use a dedicated, narrowly scoped API key for this Skill and rotate it periodically. 6. Ensure the gateway can revoke keys promptly and restrict each key to only the required send, inbox-read, and read-state operations. 7. Consider separate keys for sending and receiving if the gateway supports granular authorization. 8. Add configuration validation in `config.sh` before any request is made and produce a clear error when an insecure remote URL is supplied.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (19)

Chaining Abuse

High
Category
Tool Misuse
Content
The SMS Gateway is a self-hosted Go binary that serves both a REST API and a WebUI. Run the automated install script on your server or Raspberry Pi:

```bash
curl -fsSL https://raw.githubusercontent.com/mattboston/sms-gateway/main/install.sh | sudo bash
```

Or download and run manually:
Confidence
98% confidence
Finding
Chaining curl output directly into sudo bash combines remote retrieval, interpretation, and privileged execution into a single step with no review boundary. This sharply increases the blast radius of any compromise of the repository, maintainer account, CDN path, or TLS trust chain, enabling instant root-level arbitrary code execution.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env bash
# Configuration for SMS Gateway scripts
# Override these via environment variables or a .env file

SMS_GATEWAY_URL="${SMS_GATEWAY_URL:-http://localhost:5174}"
SMS_GATEWAY_API_KEY="${SMS_GATEWAY_API_KEY:-}"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env bash
# Configuration for SMS Gateway scripts
# Override these via environment variables or a .env file

SMS_GATEWAY_URL="${SMS_GATEWAY_URL:-http://localhost:5174}"
SMS_GATEWAY_API_KEY="${SMS_GATEWAY_API_KEY:-}"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
#!/usr/bin/env bash
# Configuration for SMS Gateway scripts
# Override these via environment variables or a .env file

SMS_GATEWAY_URL="${SMS_GATEWAY_URL:-http://localhost:5174}"
SMS_GATEWAY_API_KEY="${SMS_GATEWAY_API_KEY:-}"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
ALLOWLIST_FILE="${ALLOWLIST_FILE:-${SCRIPT_DIR}/allowlist.json}"

# Load .env file if it exists alongside these scripts
if [[ -f "${SCRIPT_DIR}/.env" ]]; then
  # shellcheck source=/dev/null
  source "${SCRIPT_DIR}/.env"
fi
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
ALLOWLIST_FILE="${ALLOWLIST_FILE:-${SCRIPT_DIR}/allowlist.json}"

# Load .env file if it exists alongside these scripts
if [[ -f "${SCRIPT_DIR}/.env" ]]; then
  # shellcheck source=/dev/null
  source "${SCRIPT_DIR}/.env"
fi
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# Load .env file if it exists alongside these scripts
if [[ -f "${SCRIPT_DIR}/.env" ]]; then
  # shellcheck source=/dev/null
  source "${SCRIPT_DIR}/.env"
fi

# Validate required settings
Confidence
82% confidence
Finding
Sourcing a .env file executes its contents as shell code, not just variable assignments. If an attacker can modify that file or influence the script directory contents, they can achieve arbitrary code execution and potentially steal the SMS gateway API key or alter runtime behavior.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
The SMS Gateway is a self-hosted Go binary that serves both a REST API and a WebUI. Run the automated install script on your server or Raspberry Pi:

```bash
curl -fsSL https://raw.githubusercontent.com/mattboston/sms-gateway/main/install.sh | sudo bash
```

Or download and run manually:
Confidence
97% confidence
Finding
The README instructs users to pipe a remotely fetched script directly into sudo bash, which gives unreviewed network content immediate root execution. If the GitHub source, network path, or account is compromised, an attacker could gain full system control during installation.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
curl -fsSL -o install.sh https://raw.githubusercontent.com/mattboston/sms-gateway/main/install.sh
chmod +x install.sh
sudo ./install.sh
```

The script installs SMS Gateway as a systemd service, prompts for your device path (e.g., `/dev/ttyUSB0`), port, and JWT secret, then starts the service automatically.
Confidence
84% confidence
Finding
This variant is safer than piping directly to bash because it separates download from execution, but it still recommends running a remotely fetched installer with sudo. Users are likely to execute the script without verification, allowing root compromise if the script source is tampered with.

Session Persistence

Medium
Category
Rogue Agent
Content
Copy the skill files into your OpenClaw workspace:

```bash
mkdir -p ~/.openclaw/workspace/skills/sms-gateway
cp -R path/to/openclaw/* ~/.openclaw/workspace/skills/sms-gateway/
```
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.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file documents commands to send and receive SMS and notes an allowlist, but it does not include any user-facing warning about privacy implications of transmitting phone numbers and message content via the GSM modem, gateway service, and mobile network. For markdown files, SQP-2 applies when the skill description omits warnings about behaviors that could affect user data or privacy.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill invokes shell scripts but does not declare an explicit tool scope such as permissions or allowed-tools. That weakens the trust boundary for the agent/runtime, making it easier for shell execution to occur without clear least-privilege constraints or review of what commands the skill may run.

Session Persistence

Medium
Category
Rogue Agent
Content
## Setup

Before using this skill, create a `.env` file in the `~/.openclaw/workspace/skills/sms-gateway/scripts` directory with the following variables:

```text
SMS_GATEWAY_URL=http://127.0.0.1:5174
Confidence
88% confidence
Finding
The skill instructs storing the API key in a persistent .env file under the workspace. Persisting secrets in a shared or agent-accessible workspace increases the chance of accidental disclosure, reuse by unrelated skills, or exfiltration if the workspace is inspected or synced.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill states later that unread messages are automatically marked as read after display, but this side effect is not prominently disclosed as a warning where users decide to view messages. That can cause unintended state changes, loss of unread status, and audit/confusion issues when an operator expects a read-only inbox query.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This script retrieves full SMS inbox contents, which are sensitive communications, and sends an API key to the gateway, yet provides no explicit warning that private messages will be read and displayed. In a skill context, this can surprise users or higher-level agents into exposing personal or operationally sensitive SMS content without informed consent.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The script's 'receive' operation is not read-only: after displaying inbox messages, it automatically marks all messages with status 'received' as read. This creates an undocumented state change that can interfere with user workflows, hide unread messages from other systems or operators, and causes side effects from a command that appears to be a simple inbox query.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
Unread messages are automatically marked as read immediately after retrieval, without warning or confirmation. That silent, irreversible state change can cause loss of operational visibility, break downstream triage processes, and conceal whether messages were genuinely reviewed by a human.

External Transmission

Medium
Category
Data Exfiltration
Content
fi

# Send the SMS
RESPONSE=$(curl -s -w "\n%{http_code}" \
  -X POST "${SMS_GATEWAY_URL}/api/v1/sms/send" \
  -H "X-API-Key: ${SMS_GATEWAY_API_KEY}" \
  -H "Content-Type: application/json" \
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Script Fetching

Low
Category
Supply Chain
Content
The SMS Gateway is a self-hosted Go binary that serves both a REST API and a WebUI. Run the automated install script on your server or Raspberry Pi:

```bash
curl -fsSL https://raw.githubusercontent.com/mattboston/sms-gateway/main/install.sh | sudo bash
```

Or download and run manually:
Confidence
95% confidence
Finding
The documentation tells users to fetch and execute an external script from a live URL. Because the content can change over time and is not pinned or verified, this creates a supply-chain risk that could lead to arbitrary code execution.

Static analysis

No suspicious patterns detected.