Back to skill

Security audit

pumpfun-sniper

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform the advertised token-risk scoring, but its web UI, payment handling, and mutable dependency instructions create risks users should review before installing.

Review this before installing or hosting. Prefer the JSON/API or CLI output over the bundled web UI until metadata rendering is fixed, pin the npm and Python dependencies, and only use a trusted x402 facilitator/payment endpoint. Treat its SNIPE/CAUTION/AVOID output as advisory trading information, not a guarantee of safety.

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

T09 · Insecure Skill Coding Practices

Error
Location
api/static/index.html:85
Finding
Stored DOM XSS Through Untrusted Token Metadata<![CDATA[ ## Vulnerability Details **File Location**: `api/static/index.html:85-119` **Vulnerability Type**: DOM-based cross-site scripting through unsafe HTML rendering **Risk Level**: High ### Vulnerable Code ```javascript res.innerHTML = ` <div class="score-ring"> <div class="ring-wrap"> <svg class="ring" width="130" height="130" viewBox="0 0 130 130"> <circle class="ring-bg" cx="65" cy="65" r="54"/> <circle class="ring-fill" cx="65" cy="65" r="54" stroke="${col}" stroke-dasharray="${circ}" stroke-dashoffset="${offset}"/> </svg> <div class="ring-num" style="color:${col}">${score}</div> </div> <div class="verdict ${d.verdict}">${d.verdict === 'SNIPE' ? '🎯 SNIPE' : d.verdict === 'CAUTION' ? '⚠️ CAUTION' : '🚨 AVOID'}</div> </div> <div class="token-bar"> <div class="ti"><span class="tl">Token</span><span class="tv">$${d.token.symbol} — ${d.token.name}</span></div> <div class="ti"><span class="tl">Price</span><span class="tv">$${parseFloat(d.token.price_usd||0).toPrecision(4)}</span></div> <div class="ti"><span class="tl">Liquidity</span><span class="tv">$${Number(d.token.liquidity_usd||0).toLocaleString()}</span></div> <div class="ti"><span class="tl">Market Cap</span><span class="tv">$${Number(d.token.market_cap||0).toLocaleString()}</span></div> </div> <div class="breakdown"> <h3>Score Breakdown</h3> ${Object.entries(d.breakdown).map(([k,v])=>` <div class="bar-row"> <span class="bar-label">${KEYS[k]||k}</span> <div class="bar-track"><div class="bar-fill" style="width:${(v.score/v.max*100)}%;background:${v.score/v.max>0.6?'#14f195':v.score/v.max>0.35?'#e3a008':'#f85149'}"></div></div> <span class="bar-num">${v.score}/${v.max}</span> </div>`).join('')} </div> <div class="signals"> <h3>Signals</h3> ${d.signals.map(s=>`<div class="signal">${s}</div>`).join('')} </div>`; ``` The values are populated f ...[truncated 2938 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not render externally sourced metadata through `innerHTML`. 2. Create DOM elements and assign untrusted values through `textContent`: ```javascript const tokenValue = document.createElement('span'); tokenValue.className = 'tv'; tokenValue.textContent = `$${d.token.symbol} — ${d.token.name}`; ``` 3. Construct signal rows individually: ```javascript for (const signal of d.signals) { const row = document.createElement('div'); row.className = 'signal'; row.textContent = String(signal); signalsContainer.appendChild(row); } ``` 4. If HTML rendering is unavoidable, sanitize every externally influenced field with a maintained allowlist-based sanitizer such as DOMPurify. Encoding must be appropriate to the destination context; HTML escaping alone is not sufficient for style, URL, or attribute contexts. 5. Validate the API response schema before rendering: - Require finite numeric values for scores and financial fields. - Restrict verdicts to `SNIPE`, `CAUTION`, or `AVOID`. - Enforce reasonable string lengths. - Treat all token names, symbols, URLs, and signals as untrusted text. 6. Add a restrictive Content Security Policy, for example by disallowing inline scripts and event handlers. Refactor the current inline script into a separate static file before enforcing such a policy. 7. Add automated tests using token metadata containing tags, event handlers, malformed markup, and encoded payloads. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:28
Finding
Mutable and Unpinned Third-Party Dependency Execution<![CDATA[ ## Vulnerability Details **File Locations**: `SKILL.md:28-31`, `requirements.txt:1-4`, `api/requirements.txt:1-4` **Vulnerability Type**: Unsafe dependency resolution and mutable package execution **Risk Level**: Medium ### Vulnerable Code `SKILL.md:28-31` instructs users to download and execute the latest available npm package version: ```bash # Check payment requirements npx awal@latest x402 details https://pumpfun-sniper-production.up.railway.app/score?ca=TOKEN_CA # Score a token (auto-pays) npx awal@latest x402 pay "https://pumpfun-sniper-production.up.railway.app/score?ca=TOKEN_CA" ``` Both `requirements.txt:1-4` and `api/requirements.txt:1-4` specify only lower bounds: ```text fastapi>=0.110.0 uvicorn>=0.29.0 requests>=2.28.0 aiofiles>=23.2.0 ``` ### Technical Analysis The `npx awal@latest` instruction resolves a mutable package release and may download and execute package code that was not part of this audit. The effective code can therefore change after the Skill is reviewed. The Python dependency specifications similarly permit any future compatible or incompatible release above the minimum version. They contain no exact pins, lockfile references, or package hashes. Consequently, two installations at different times may execute materially different dependency code. No evidence was found that the currently named dependencies are malicious. The vulnerability is the absence of reproducible, integrity-checked dependency resolution, which expands the supply-chain attack surface. ### Attack Path A supply-chain exploitation path would be: 1. A dependency publisher account, package registry, or dependency release process is compromised, or a future release introduces malicious installation/runtime behavior. 2. A user follows the documented `npx awal@latest` command or runs `pip install -r api/requirements.txt`. 3. The package manager resolves the changed upstream release because no audited exact version is required. 4. The package’s insta ...[truncated 916 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `awal@latest` with an exact, reviewed version: ```bash npx awal@<audited-version> x402 details ... npx awal@<audited-version> x402 pay ... ``` 2. Prefer installing from a lockfile and use `npm ci` or an equivalent reproducible workflow. 3. Commit and verify npm lockfile integrity information where the CLI is part of the supported workflow. 4. Pin Python dependencies to exact reviewed versions rather than unrestricted lower bounds: ```text fastapi==<reviewed-version> uvicorn==<reviewed-version> requests==<reviewed-version> aiofiles==<reviewed-version> ``` 5. Generate hashes for all Python packages and transitive dependencies, then install with hash verification: ```bash pip install --require-hashes -r requirements.lock ``` 6. Use an automated dependency update process that opens reviewable changes, runs security scans and tests, and updates pins only after approval. 7. Document the package source, expected publisher, audited version, and integrity-checking procedure for payment-related command-line tools. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (54)

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

Critical
Category
Data Flow
Content
if not ph:
        return False
    try:
        r = requests.post(f"{FACILITATOR}/verify",
                          json={"payment": ph, "paymentRequirements": payment_requirements()["accepts"][0]},
                          timeout=10)
        return r.status_code == 200 and r.json().get("isValid", False)
Confidence
93% confidence
Finding
The facilitator URL is taken directly from an environment variable and used for a server-side POST that includes the X-PAYMENT token. If an attacker or misconfiguration points FACILITATOR to an untrusted host, payment credentials and request metadata are exfiltrated and payment validation can be delegated to a malicious service. In a paid API, this directly affects billing integrity and can also become an SSRF-style outbound connection primitive.

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

Critical
Category
Data Flow
Content
def settle_payment(ph: str) -> dict:
    try:
        r = requests.post(f"{FACILITATOR}/settle",
                          json={"payment": ph, "paymentRequirements": payment_requirements()["accepts"][0]},
                          timeout=10)
        return r.json() if r.status_code == 200 else {}
Confidence
93% confidence
Finding
The settlement call also sends the payment header to a facilitator URL fully controlled by environment configuration. A malicious or compromised FACILITATOR can harvest payment data, forge settlement outcomes, or manipulate transaction lifecycle behavior. Because this occurs after scoring, it can corrupt billing records or leak reusable payment artifacts to an attacker-controlled service.

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

Critical
Category
Data Flow
Content
def rpc(method, params):
    for url in RPC_ENDPOINTS:
        try:
            r = requests.post(url, json={"jsonrpc": "2.0", "id": 1,
                                          "method": method, "params": params},
                              headers=HEADERS, timeout=8)
            if r.status_code == 200:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
Data Flow
Content
]
    for url in urls:
        try:
            r = requests.get(url, headers=HEADERS, timeout=6)
            if r.status_code == 200:
                return r.json()
        except Exception:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
Data Flow
Content
return []
    try:
        url = f"https://api.helius.xyz/v0/addresses/{wallet}/transactions?api-key={HELIUS_KEY}&limit={limit}"
        r = requests.get(url, headers=HEADERS, timeout=8)
        if r.status_code == 200:
            return r.json()
    except Exception:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Ae3

High
Category
analysis-evasion
Confidence
90% confidence
Finding
Text artifact contains embedded NUL bytes

Ae3

High
Category
analysis-evasion
Confidence
90% confidence
Finding
The file appears to be a pax extended header or metadata artifact rather than normal skill content, and it includes embedded NUL/control bytes in the provenance xattr value. Such bytes can confuse parsers, truncation-sensitive tooling, or downstream scanners that assume UTF-8 text, creating opportunities for hidden content, misclassification, or processing errors in the skill packaging pipeline.

Ae3

High
Category
analysis-evasion
Confidence
90% confidence
Finding
Text artifact contains embedded NUL bytes

Ae3

High
Category
analysis-evasion
Confidence
90% confidence
Finding
The file appears to be a tar/PAX header artifact containing binary extended-attribute data represented in a text-like file. Embedded NUL and other non-printable bytes are risky because downstream tooling may mis-parse the file, truncate processing at the NUL, or behave inconsistently across platforms, which can hide metadata or break security scanning. In a skill package, opaque archive metadata is more suspicious because it can conceal provenance fields or trigger parser edge cases during ingestion.

Ae3

High
Category
analysis-evasion
Confidence
90% confidence
Finding
Text artifact contains embedded NUL bytes

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This is a clear description-to-behavior mismatch. The declared purpose describes a substantive crypto risk-analysis tool for pump.fun tokens, but the provided code chunk contains only file/archive metadata entries and no functional implementation. Because there is no observable logic supporting the claimed analysis capabilities, the actual behavior shown does not match the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
There is a clear mismatch because the declared description promises a token safety analysis tool with multiple risk checks and scoring behavior, but the provided code chunk contains only file/archive metadata and no substantive implementation. Based on the supplied code, the skill does not demonstrate the stated primary purpose or any of the claimed analytical capabilities.

Ae3

High
Category
analysis-evasion
Confidence
90% confidence
Finding
Text artifact contains embedded NUL bytes

Ae3

High
Category
analysis-evasion
Confidence
90% confidence
Finding
Text artifact contains embedded NUL bytes

Ae3

High
Category
analysis-evasion
Confidence
90% confidence
Finding
Text artifact contains embedded NUL bytes

Possible Typosquatting: 'uvicorn' resembles popular package 'gunicorn'

High
Category
Supply Chain
Confidence
70% confidence
Finding
Package name closely resembles a popular package, suggesting possible typosquatting. Attackers publish malicious packages with similar names to trick developers into installing them.

Possible Typosquatting: 'uvicorn' resembles popular package 'gunicorn'

High
Category
Supply Chain
Confidence
70% confidence
Finding
Package name closely resembles a popular package, suggesting possible typosquatting. Attackers publish malicious packages with similar names to trick developers into installing them.

Ae3

High
Category
analysis-evasion
Confidence
90% confidence
Finding
Text artifact contains embedded NUL bytes

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
The presence of unusual/binary-looking metadata fields and mixed encoding indicators in a markdown-named file suggests malformed archive content or encoding abuse. Even if not overtly malicious, this can bypass human review and static analysis by making the apparent text differ from what tools normalize or display, which is risky in a security-sensitive agent skill supply chain.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
The header contains suspicious non-standard or mixed encoding content, likely from archive metadata fields and platform-specific provenance attributes. While not necessarily malicious on its own, unusual Unicode or normalization issues can be used to confuse reviewers, cause filename/metadata mismatches, or bypass simplistic validation logic; in a security-sensitive skill distribution context, that makes the artifact more concerning than ordinary text corruption.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares executable/network-related capabilities via `python3`, an API key, and documented external API usage, but it does not define an explicit tool scope such as permissions or allowed-tools. This weakens containment and reviewability because an agent may invoke code or network access more broadly than the manifest makes clear, increasing the chance of unintended data exposure or unsafe execution paths.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
Using `npx awal@latest` pulls and executes the latest package version at runtime, creating a supply-chain risk. If the upstream package is compromised or a breaking/malicious version is published, users or agents following the skill instructions could execute attacker-controlled code.

Static analysis

No suspicious patterns detected.