Back to skill

Security audit

RunBox — Paid Code Execution for AI Agents

Security checks for vulnerabilities and agentic risk

Overview

RunBox openly provides paid remote code execution, but it can automatically spend real Stellar USDC through an insecure HTTP payment flow with weak limits and user control.

Review before installing. Use only a dedicated low-balance Stellar wallet, prefer testnet, avoid submitting sensitive code or secrets, and do not allow automatic mainnet payment unless you trust the endpoint and accept that server responses can trigger irreversible USDC transfers.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
run.py:141
Finding

Unauthenticated Server Response Controls Autonomous Mainnet Payment

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
run.py:174
Finding

User Code and Session Bearer Token Are Transmitted Over Cleartext HTTP

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Wallet-Sensitive Dependencies Are Installed Without Reproducible Version Pinning

Content
View full analysis
=10.0.0 requests>=2.31.0 ``` The Skill metadata additionally instructs installation without version constraints: ```yaml python_packages: [stellar-sdk, requests, python-dotenv] install: | pip install stellar-sdk requests python-dotenv ``` ### Technical Analysis The dependency declarations use open-ended minimum versions, while the installation instructions request the latest available versions. Consequently, installations performed at different times can resolve to materially different code without a corresponding change to the audited Skill. These packages execute in a process that has access to `STELLAR_SECRET_KEY` and performs wallet transaction signing. A compromised, malicious, or unexpectedly incompatible future package release could therefore access the process environment, alter transaction construction, redirect network operations, or leak credentials. There is also a consistency issue: `python-dotenv` is listed and installed by `SKILL.md`, but it is absent from `requirements.txt` and unused by the reviewed executable. Installing an unnecessary package increases supply-chain exposure without supporting the declared runtime behavior. No currently malicious dependency was established during this static audit. The vulnerability is the absence of reproducible and minimal dependency controls. ### Attack Path 1. The Skill is installed using the provided `pip install` instructions or open-ended requirements. 2. Package resolution selects a newer release than the version originally audited. 3. The selected release is compromised, malicious, or contains unsafe import-time behavior. 4. The dependency executes in the same Python process as the Skill. 5. It reads environment vari ...[truncated 704 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (31)

Tainted flow: 'rent_url' from os.environ.get (line 133, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The endpoint used for the rent request is derived from an environment variable and defaults to plain HTTP, so a user or attacker controlling configuration or network position can redirect requests to an untrusted server. In this skill, that server dictates payment instructions, meaning the client may autonomously send real USDC to an attacker-controlled destination before executing code.

Content

Scanner excerpt · run.py (reported line 136)May include surrounding context.

python
rent_url = f"{RUNBOX_ENDPOINT}/api/exec/rent"

    print("Requesting RunBox session...", file=sys.stderr)
    r = requests.post(rent_url, json={"language": language}, timeout=15)

    if r.status_code == 200:
        return r.json()

Tainted flow: 'rent_url' from os.environ.get (line 133, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

After making a blockchain payment, the client retries session creation against the same configurable endpoint without authenticating that the service is legitimate. If the endpoint was malicious or tampered with, the tool can both lose funds and disclose payment proof to an attacker while obtaining a fake session token.

Content

Scanner excerpt · run.py (reported line 167)May include surrounding context.

python
# Retry with payment proof
    # For x402, the client would normally include a signed auth entry.
    # Here we include the tx hash as proof for the server to verify.
    retry = requests.post(
        rent_url,
        json={"language": language},
        headers={"X-Payment-Hash": tx["hash"], "X-Payment-Network": network},

Tainted flow: 'RUNBOX_ENDPOINT' from os.environ.get (line 34, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The code execution request sends both user code and a bearer session token to a configurable endpoint that also defaults to insecure HTTP. If redirected or intercepted, an attacker can steal the session token, read submitted code, and impersonate the client against the remote execution service.

Content

Scanner excerpt · run.py (reported line 183)May include surrounding context.

python
def run_code(session_token: str, language: str, code: str) -> dict:
    """Execute code using a valid session token."""
    r = requests.post(
        f"{RUNBOX_ENDPOINT}/api/exec/run",
        json={"language": language, "code": code},
        headers={"Authorization": f"Bearer {session_token}"},

Tainted flow: 'rent_url' from os.environ.get (line 133, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/run.py (reported line 136)May include surrounding context.

python
rent_url = f"{RUNBOX_ENDPOINT}/api/exec/rent"

    print("Requesting RunBox session...", file=sys.stderr)
    r = requests.post(rent_url, json={"language": language}, timeout=15)

    if r.status_code == 200:
        return r.json()

Tainted flow: 'rent_url' from os.environ.get (line 133, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/run.py (reported line 167)May include surrounding context.

python
# Retry with payment proof
    # For x402, the client would normally include a signed auth entry.
    # Here we include the tx hash as proof for the server to verify.
    retry = requests.post(
        rent_url,
        json={"language": language},
        headers={"X-Payment-Hash": tx["hash"], "X-Payment-Network": network},

Tainted flow: 'RUNBOX_ENDPOINT' from os.environ.get (line 34, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The script sends the user's code and bearer session token to a configurable remote endpoint, defaulting to plain HTTP. If the endpoint is malicious or traffic is intercepted, sensitive code, execution data, and reusable session credentials can be exposed or altered; in this skill, remote execution is the core feature, so endpoint trust and transport security are especially critical.

Content

Scanner excerpt · scripts/run.py (reported line 183)May include surrounding context.

python
def run_code(session_token: str, language: str, code: str) -> dict:
    """Execute code using a valid session token."""
    r = requests.post(
        f"{RUNBOX_ENDPOINT}/api/exec/run",
        json={"language": language, "code": code},
        headers={"Authorization": f"Bearer {session_token}"},

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README explicitly instructs an agent to autonomously spend funds from a configured Stellar wallet whenever a user asks to run code, asserting that 'the user has already funded your Stellar wallet.' In an agent-skill context, this creates a real risk of unauthorized or unintended financial transactions because the agent may initiate blockchain payments without explicit per-transaction user consent or spending limits.

Content

No source excerpt is available for this finding.

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 169)May include surrounding context.

bash
git clone https://github.com/daraijaola/Runbox.git
cd Runbox
cp .env.example .env   # fill in STELLAR_RECEIVE_ADDRESS and SESSION_JWT_SECRET
pnpm install
pnpm --filter @workspace/api-server run build
pnpm --filter @workspace/api-server run start

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 · SKILL.md (reported line 205)May include surrounding context.

bash
git clone https://github.com/daraijaola/Runbox.git
cd Runbox
cp .env.example .env   # fill in STELLAR_RECEIVE_ADDRESS and SESSION_JWT_SECRET
pnpm install
pnpm --filter @workspace/api-server run build
pnpm --filter @workspace/api-server run start

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill promotes automatic invocation and states 'No human approval' while omitting a prominent warning that real funds may be spent from the configured Stellar wallet. This is especially dangerous because the skill is user-invocable and designed for autonomous payment, so users and operators may unknowingly authorize financial transactions and remote code submission merely by making common requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code submits a live Stellar payment automatically, and mainnet is the default network. A user invoking code execution may unknowingly authorize real cryptocurrency spending, and a malicious or compromised service can repeatedly induce charges or manipulate pricing targets within the payment flow.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The system-prompt example instructs the agent to use STELLAR_SECRET_KEY to pay autonomously as part of normal task handling. Embedding payment behavior into a reusable system prompt is dangerous because it encourages agents to treat spending as routine tool use, making prompt injection, ambiguous requests, or malicious user tasks more likely to trigger real-money transactions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The setup instructions tell users to export STELLAR_SECRET_KEY directly for automated use without prominent guidance on secure secret handling, storage, rotation, or scope minimization. In agent environments, exposing a signing key this way increases the chance of accidental disclosure through logs, process inspection, misconfigured toolchains, or prompt-induced misuse.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly requires a wallet secret and communicates with a remote endpoint, yet it declares no tool scope or permission boundaries. In an agent ecosystem, this means the skill can be auto-invoked with access to sensitive environment data and outbound network behavior without clear operator consent, increasing the chance of unintended secret use and autonomous spending.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The invocation guidance is broad enough to match many ordinary requests such as 'calculate', 'test this', or 'write and run a Python script', causing the agent to trigger a paid remote execution service in situations where it could answer locally. Because invocation can autonomously spend funds and send user-provided code/content to an external server, overbroad triggers materially increase the risk of unnecessary charges and data exfiltration.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · run.py (reported line 183)May include surrounding context.

python
def run_code(session_token: str, language: str, code: str) -> dict:
    """Execute code using a valid session token."""
    r = requests.post(
        f"{RUNBOX_ENDPOINT}/api/exec/run",
        json={"language": language, "code": code},
        headers={"Authorization": f"Bearer {session_token}"},

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill prints the reusable session token directly to stderr, exposing a bearer credential to shell history capture, logs, CI output, terminal recorders, or other observers. Because the token authorizes remote code execution, anyone who sees it can reuse the paid session until expiry.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill loads a Stellar secret key from the environment and uses it to sign real USDC payments. Combining remote code-execution functionality with autonomous wallet spending greatly increases blast radius: compromise of the endpoint, invocation flow, or surrounding agent can directly trigger financial loss.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · run.py (reported line 136)May include surrounding context.

python
rent_url = f"{RUNBOX_ENDPOINT}/api/exec/rent"

    print("Requesting RunBox session...", file=sys.stderr)
    r = requests.post(rent_url, json={"language": language}, timeout=15)

    if r.status_code == 200:
        return r.json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · scripts/run.py (reported line 136)May include surrounding context.

python
rent_url = f"{RUNBOX_ENDPOINT}/api/exec/rent"

    print("Requesting RunBox session...", file=sys.stderr)
    r = requests.post(rent_url, json={"language": language}, timeout=15)

    if r.status_code == 200:
        return r.json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · run.py (reported line 167)May include surrounding context.

python
# Retry with payment proof
    # For x402, the client would normally include a signed auth entry.
    # Here we include the tx hash as proof for the server to verify.
    retry = requests.post(
        rent_url,
        json={"language": language},
        headers={"X-Payment-Hash": tx["hash"], "X-Payment-Network": network},

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · scripts/run.py (reported line 167)May include surrounding context.

python
# Retry with payment proof
    # For x402, the client would normally include a signed auth entry.
    # Here we include the tx hash as proof for the server to verify.
    retry = requests.post(
        rent_url,
        json={"language": language},
        headers={"X-Payment-Hash": tx["hash"], "X-Payment-Network": network},

Tainted flow: 'tx' from requests.post (line 160, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · run.py (reported line 167)May include surrounding context.

python
# Retry with payment proof
    # For x402, the client would normally include a signed auth entry.
    # Here we include the tx hash as proof for the server to verify.
    retry = requests.post(
        rent_url,
        json={"language": language},
        headers={"X-Payment-Hash": tx["hash"], "X-Payment-Network": network},

Tainted flow: 'tx' from requests.post (line 160, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/run.py (reported line 167)May include surrounding context.

python
# Retry with payment proof
    # For x402, the client would normally include a signed auth entry.
    # Here we include the tx hash as proof for the server to verify.
    retry = requests.post(
        rent_url,
        json={"language": language},
        headers={"X-Payment-Hash": tx["hash"], "X-Payment-Network": network},

Static analysis

No suspicious patterns detected.