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

Content
View full analysis

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
View 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

Content
View full analysis

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

Content

Scanner excerpt · README.md (reported line 20)May include surrounding context.

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:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 69)May include surrounding context.

md
#!/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:-}"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · config.sh (reported line 3)May include surrounding context.

sh
#!/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:-}"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · config.sh (reported line 12)May include surrounding context.

sh
#!/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:-}"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · config.sh (reported line 13)May include surrounding context.

sh
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

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · config.sh (reported line 21)May include surrounding context.

sh
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

Credential Access

High
Category
Privilege Escalation
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.

Content

Scanner excerpt · config.sh (reported line 15)May include surrounding context.

sh
# 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

Sudo/Root Execution

Medium
Category
Privilege Escalation
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.

Content

Scanner excerpt · README.md (reported line 20)May include surrounding context.

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:

Sudo/Root Execution

Medium
Category
Privilege Escalation
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.

Content

Scanner excerpt · README.md (reported line 28)May include surrounding context.

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.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · README.md (reported line 51)May include surrounding context.

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/

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · SKILL.md (reported line 25)May include surrounding context.

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

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · send_sms.sh (reported line 49)May include surrounding context.

sh
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" \

External Script Fetching

Low
Category
Supply Chain
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.

Content

Scanner excerpt · README.md (reported line 20)May include surrounding context.

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: