Back to skill

Security audit

QELT Blockchain

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent QELT blockchain helper, but one example can let a malicious RPC response become local Python execution, so it should be reviewed before use.

Install only if you are comfortable reviewing or avoiding the vulnerable event-log shell snippet. Use safer parsing that validates RPC results as hex data before conversion, and confirm network and transaction intent before submitting any pre-signed mainnet transaction.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:121
Finding

Untrusted JSON-RPC Response Interpolated into Executable Python Code

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 121–127
Vulnerability Type: Code injection through unsafe interpolation of network-controlled data
Risk Level: High

Vulnerable Code

bash
LATEST=$(curl -fsSL -X POST https://mainnet.qelt.ai \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' | python3 -c "import sys,json; print(json.load(sys.stdin)['result'])")

# Then query a bounded recent range (last ~1000 blocks ≈ 83 minutes on QELT)
# Clamp at 0 so the start block is never negative on a low-height chain (e.g. fresh testnet).
FROM_HEX=$(python3 -c "latest=int('$LATEST',16); print(hex(max(0, latest - 1000)))")

Technical Analysis

The LATEST variable is derived from a remote JSON-RPC response. Although the response is parsed as JSON, the resulting result field is not validated as a hexadecimal block number. It is subsequently interpolated directly into a double-quoted python3 -c argument:

python
latest=int('$LATEST',16)

Shell expansion occurs before Python parses this source. A malicious result value containing quote characters and Python syntax can terminate the intended string literal and introduce additional executable statements. Consequently, a read-only network query can become arbitrary local Python execution.

This behavior is not necessary for the skill's declared blockchain-query functionality and violates least-privilege principles. The block-range calculation can be performed while treating the RPC value strictly as data.

The pre-scan warning concerning a curl | bash remote-script pipeline was not confirmed. The audited files contain direct JSON-RPC curl requests, not remote shell-script execution. The vulnerability instead arises from unsafe interpolation of one response into a later Python program.

Attack Path

  1. An attacker compromises, impersonates, or otherwise controls the con ...[truncated 1171 chars]
Remediation
View remediation

Remediation Suggestions

Treat the RPC result as data rather than interpolating it into source code:

  1. Validate that the value is a string matching the strict pattern 0x[0-9a-fA-F]+.
  2. Pass the value through an environment variable, standard input, or a positional argument.
  3. Keep the Python program in a single-quoted shell string so shell expansion cannot modify its source.
  4. Fail closed when JSON parsing, type checking, or hexadecimal validation fails.
  5. Prefer parsing the response and calculating the range in one process to minimize trust-boundary crossings.

One hardened approach is:

bash
FROM_HEX=$(
  curl -fsSL -X POST https://mainnet.qelt.ai \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' |
  python3 -c '
import json
import re
import sys

response = json.load(sys.stdin)
value = response.get("result")

if not isinstance(value, str) or re.fullmatch(r"0x[0-9a-fA-F]+", value) is None:
    raise SystemExit("Invalid block number returned by RPC endpoint")

print(hex(max(0, int(value, 16) - 1000)))
'
)

This version never inserts the remote value into executable source and rejects malformed or malicious responses before conversion.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · CONTRIBUTING.md (reported line 58)May include surrounding context.

md
## Adding New Examples to the Skill

Update SKILL.md when new use-cases arise.
- Keep the Safety section accurate
- Add new JSON-RPC methods in the correct category
- Include working curl examples with realistic placeholders

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

Get Latest Block Number

bash
curl -fsSL -X POST https://mainnet.qelt.ai \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · CONTRIBUTING.md (reported line 24)May include surrounding context.

  1. Test the JSON-RPC call directly in your terminal to isolate the issue:
    bash
    curl -fsSL -X POST https://mainnet.qelt.ai \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
    

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SKILL.md (reported line 50)May include surrounding context.

Get Latest Block Number

bash
curl -fsSL -X POST https://mainnet.qelt.ai \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SKILL.md (reported line 129)May include surrounding context.

Clamp at 0 so the start block is never negative on a low-height chain (e.g. fresh testnet).

FROM_HEX=$(python3 -c "latest=int('$LATEST',16); print(hex(max(0, latest - 1000)))")

curl -fsSL -X POST https://mainnet.qelt.ai
-H "Content-Type: application/json"
-d "{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock":"$FROM_HEX","toBlock":"latest","address":"0xCONTRACT","topics":["0xTOPIC"]}],"id":1}"

text

Static analysis

No suspicious patterns detected.