Back to skill

Security audit

Windfall Inference

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to provide the advertised inference gateway, but its included service code has serious review-worthy security issues around wallet-linked accounts, browser credential storage, payment/proxy trust, and server installation.

Review before installing or using with sensitive workloads. Treat Windfall as a third-party proxy that can see prompts and route them to OpenRouter; avoid production secrets or confidential prompts until the wallet-auth, dashboard XSS, localStorage credential, peer-proxy, dependency, and deployment-script issues are addressed.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
deploy/setup.sh:10
Finding
Root-Level Execution of a Mutable Remote Installation Script<![CDATA[ ## Vulnerability Details **File Location**: `deploy/setup.sh:10-13` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: Critical ### Vulnerable Code ```bash # Install Node.js 22 LTS if ! command -v node &> /dev/null; then echo "Installing Node.js 22..." curl -fsSL https://deb.nodesource.com/setup_22.x | bash - apt-get install -y nodejs fi ``` ### Technical Analysis The setup script downloads content from a remote URL and passes it directly to Bash. The response is not pinned to a version, inspected, signature-verified, or checked against a known digest before execution. The surrounding commands install system packages and create directories under `/opt`, indicating that the script is intended to run with root privileges. Consequently, the remotely supplied script also executes with root authority. NodeSource is a recognizable package provider, and there is no evidence that its current script is malicious. However, the effective code executed by this project can change after the project itself has been reviewed. A compromise of the remote endpoint, upstream publication process, DNS resolution, or TLS trust chain would therefore become arbitrary root code execution. ### Attack Path 1. An administrator runs `deploy/setup.sh` with root privileges on a fresh server. 2. The script requests the current content of `https://deb.nodesource.com/setup_22.x`. 3. A compromised or unexpectedly modified response is streamed directly into Bash. 4. Bash executes the response without local review or integrity verification. 5. The remote payload gains root-level access to the host. ### Impact Assessment A successful supply-chain compromise could obtain complete control of the deployment server. The resulting privileges could include: - Reading application secrets and wallet private keys. - Replacing the inference service or its dependencies. - Modifying payment destinations or transaction logic. - Installing persistent service ...[truncated 156 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `curl | bash` pipeline. 2. Prefer Ubuntu's signed package repositories or a repository configured through a locally reviewed procedure. 3. Install repository signing keys using a dedicated keyring rather than globally trusting a downloaded key. 4. Pin the Node.js major and package versions used in production. 5. If a standalone artifact is required: - Download it to a temporary file. - Verify its publisher signature. - Compare its SHA-256 digest with a pinned, trusted value. - Inspect or execute it only after verification succeeds. 6. Run installation steps with the minimum privileges needed instead of executing an entire mutable script as root. 7. Record verified artifact versions and hashes in deployment documentation for reproducible builds. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
public/dashboard.html:263
Finding
Stored Cross-Site Scripting Through Unsanitized API-Key Labels<![CDATA[ ## Vulnerability Details **File Location**: `public/dashboard.html:263-276`; source-to-sink chain through `src/index.ts:371-384`, `src/services/api-keys.ts:73-90`, and `src/index.ts:518-545` **Vulnerability Type**: Stored cross-site scripting **Risk Level**: High ### Vulnerable Code The public API accepts a caller-controlled label: ```typescript app.post('/api/keys', keyCreationLimiter, async (req, res) => { try { const { wallet_address, label } = req.body || {}; // Check onchain identity to determine free request tier const identity = await checkIdentity(wallet_address); const result = createApiKey( wallet_address, label, identity.tier, identity.freeRequests, ); ``` The label is stored without content validation or a length restriction: ```typescript export function createApiKey( walletAddress?: string, label?: string, identityTier?: string, freeRequests?: number, ): { key: string; info: ApiKeyInfo } { const db = getDb(); const key = generateKey(); const keyHash = hashKey(key); const keyPrefix = key.slice(0, 12) + '...'; const now = new Date().toISOString(); const tier = identityTier || 'anonymous'; const free = freeRequests ?? DEFAULT_FREE_REQUESTS; db.prepare(` INSERT INTO api_keys (key_prefix, key_hash, wallet_address, label, identity_tier, free_requests_remaining, created_at) VALUES (?, ?, ?, ?, ?, ?, ?) `).run(keyPrefix, keyHash, walletAddress?.toLowerCase() || null, label || null, tier, free, now); ``` It is later returned to the wallet dashboard and inserted into an HTML string: ```javascript // Show keys list for wallet auth if (authMode === 'wallet' && data.keys && data.keys.length > 0) { keysListSection.classList.remove('hidden'); keysList.innerHTML = data.keys.map(function(k) { return '<div class="flex items-center justify-between bg-white rounded-lg border border-warm-200 px-4 py-3">' + '<div>' + '<span class="font-mono text-sm t ...[truncated 2693 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Stop constructing the key list with `innerHTML`. 2. Create DOM elements and assign every untrusted value through `textContent`. 3. Validate labels on the server: - Require a string type. - Apply a conservative maximum length. - Reject control characters and unexpected markup where labels are intended to be plain text. 4. Require an authenticated wallet session before associating a key with a wallet. 5. Derive the wallet address from the verified session instead of accepting it from the request body. 6. Remove `'unsafe-inline'` from the Content Security Policy. 7. Move inline scripts to external, same-origin files or use per-response CSP nonces. 8. Review every other use of `innerHTML` and ensure only constant application-owned markup reaches those sinks. 9. Remove existing unsafe labels from the database or encode them safely before display. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/index.ts:371
Finding
Unauthenticated Wallet Impersonation During API-Key Creation<![CDATA[ ## Vulnerability Details **File Location**: `src/index.ts:371-384` **Vulnerability Type**: Missing authorization for wallet-linked identity privileges **Risk Level**: High ### Vulnerable Code ```typescript app.post('/api/keys', keyCreationLimiter, async (req, res) => { try { const { wallet_address, label } = req.body || {}; // Check onchain identity to determine free request tier const identity = await checkIdentity(wallet_address); const result = createApiKey( wallet_address, label, identity.tier, identity.freeRequests, ); ``` ### Technical Analysis The endpoint trusts a wallet address supplied in an unauthenticated request. It uses that address both to determine the on-chain identity tier and to associate the generated key with the wallet. A blockchain address is public information and is not proof of wallet control. The endpoint does not require a fresh nonce, wallet signature, or existing authenticated wallet session before granting benefits tied to the address. Consequently, any caller can claim an address that has a Basename or ERC-8004 identity and receive the corresponding free-request tier. The same missing ownership verification lets attackers insert API-key records and labels into another wallet's dashboard. This also enables the stored-XSS delivery path described separately. ### Attack Path 1. The attacker identifies a public wallet with a privileged on-chain identity. 2. The attacker submits the address as `wallet_address` to `POST /api/keys`. 3. `checkIdentity` evaluates the victim's address rather than an authenticated caller identity. 4. The server generates a key with the victim's identity tier and free-request allowance. 5. The attacker receives and uses the newly generated key. 6. The created record also appears in the victim's wallet dashboard because it is associated with the victim's address. The configured rate limiter reduces request volume from a single perceived client ...[truncated 704 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require wallet authentication before creating any wallet-linked API key. 2. Use a fresh, single-use nonce and a domain-bound SIWE message. 3. Verify the message's domain, URI, chain ID, issued-at time, expiration time, nonce, and requested action. 4. Derive the wallet address exclusively from the verified server-side session. 5. Do not accept a different `wallet_address` in the request body. 6. Permit anonymous key creation only when no wallet identity benefits or wallet association are assigned. 7. Track whether a privileged identity grant has already been claimed and enforce an appropriate uniqueness policy. 8. Apply account-level abuse controls in addition to IP-based rate limiting. 9. Audit and remove wallet associations created without ownership proof where operationally feasible. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
public/dashboard.html:336
Finding
Long-Lived API Keys and Wallet Bearer Sessions Stored in localStorage<![CDATA[ ## Vulnerability Details **File Location**: `public/dashboard.html:336-337`, `public/dashboard.html:391-399`, and `public/dashboard.html:441-449` **Vulnerability Type**: Insecure client-side credential storage **Risk Level**: Medium ### Vulnerable Code ```javascript // Save session localStorage.setItem('wf_wallet_session', session.token); localStorage.setItem('wf_wallet_address', address); // Fetch dashboard data await loadWalletDashboard(session.token, address); ``` ```javascript var res = await fetch('/api/keys/me', { headers: { 'Authorization': 'Bearer ' + key }, }); var data = await res.json(); if (res.ok) { localStorage.setItem('windfall_key', key); subtitle.textContent = data.keyPrefix + ' (' + (data.label || 'no label') + ')'; renderDashboard(data, 'api_key'); } ``` ```javascript // --- Auto-restore session --- var savedSession = localStorage.getItem('wf_wallet_session'); var savedAddress = localStorage.getItem('wf_wallet_address'); var savedKey = localStorage.getItem('windfall_key'); if (savedSession && savedAddress) { loadWalletDashboard(savedSession, savedAddress); } else if (savedKey) { apiKeyInput.value = savedKey; apiKeyInput.dispatchEvent(new Event('input')); } ``` ### Technical Analysis `localStorage` is persistent and readable by any JavaScript executing in the same origin. It does not support the `HttpOnly` protection available to cookies. The application stores both the wallet bearer-session token and the complete inference API key in this browser-accessible location. The server configures wallet sessions with a 24-hour maximum age. The full API key may remain in browser storage until the user explicitly signs out or clears site data. This broadens the exposure window following cross-site scripting, malicious browser extensions, shared-device access, or compromised same-origin JavaScript. This weakness materially increases the impact of the confirmed stored-XSS vulnerability. ### Attack Path 1. A victim a ...[truncated 957 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store wallet sessions in cookies configured with: - `Secure` - `HttpOnly` - `SameSite=Strict` - A narrowly scoped `Path` - An appropriate expiration 2. Add CSRF protection for state-changing routes if cookie-based authentication is adopted. 3. Do not persist full API keys in `localStorage` or `sessionStorage`. 4. Keep manually entered API keys in memory only, or require users to re-enter them after navigation or reload. 5. Add a server-side session-revocation endpoint and invoke it during sign-out. 6. Shorten session lifetime and rotate session tokens after authentication-sensitive operations. 7. Maintain a strict Content Security Policy and eliminate HTML injection sinks. 8. Warn users against entering persistent production credentials on shared devices. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/routes/inference.ts:151
Finding
Unsigned Peer Payment-Verification Headers and Plaintext Inter-Node Proxying<![CDATA[ ## Vulnerability Details **File Location**: `src/routes/inference.ts:151-157` and `src/routes/inference.ts:348-371` **Vulnerability Type**: Weak peer authentication and plaintext transmission of inference data **Risk Level**: High ### Vulnerable Code The destination trusts unsigned headers and a substring IP comparison: ```typescript // Verify proxied requests come from known peer node IPs only const proxyNodeId = req.headers['x-proxied-from'] as string; const clientIp = req.ip || req.socket?.remoteAddress || ''; const isProxied = req.headers['x-payment-verified'] === 'true' && proxyNodeId && config.nodes.some(n => n.id === proxyNodeId && clientIp.includes(n.ip)); if (isProxied) { payment = { method: 'free_tier', walletAddress: walletAddress || 'proxied', amountUsd: 0 }; } ``` The source sends prompts and wallet metadata over plaintext HTTP: ```typescript try { const proxyHeaders: Record<string, string> = { 'Content-Type': 'application/json', 'X-Proxied-From': config.nodeId, 'X-Payment-Verified': 'true', }; if (walletAddress) proxyHeaders['X-Wallet-Address'] = walletAddress; const proxyRes = await fetch(`http://${routing.nodeIp}:${config.port}/v1/chat/completions`, { method: 'POST', headers: proxyHeaders, body: JSON.stringify({ ...body, model, _payment_verified: true }), signal: AbortSignal.timeout(60000), }); const proxyData = await proxyRes.json(); return res.status(proxyRes.status).json(proxyData); } catch (proxyErr) { console.error(`[inference] Proxy to ${routing.nodeId} failed, falling back to local:`, proxyErr); } ``` ### Technical Analysis A request is considered paid when it carries two ordinary HTTP headers and appears to originate from an address whose string contains a configured peer IP. There is no request signature, shared-secret MAC, mutually authenticated TLS identity, timestamp, nonce, or replay protection. The application also sets Express `trust proxy` to one hop. Correctn ...[truncated 2067 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use mutually authenticated TLS between every pair of peer nodes. 2. Give each node an independent identity and narrowly scoped credential. 3. Sign or MAC a canonical representation of every proxied request, including: - HTTP method and route. - Request-body hash. - Source and destination node IDs. - Payment method and verified amount. - Timestamp and short expiration. - Cryptographically random nonce. 4. Verify the signature and reject expired or replayed nonces before trusting payment status. 5. Do not use an unsigned `X-Payment-Verified` header as an authorization decision. 6. Replace substring matching with exact comparison of normalized IP addresses. 7. Configure Express proxy trust using explicit trusted proxy addresses or CIDR ranges rather than only a hop count. 8. Configure the front proxy to remove all client-supplied forwarding and internal trust headers. 9. Restrict peer service ports through host and network firewalls so only authenticated peers can connect. 10. Avoid forwarding wallet addresses unless operationally necessary, and document the cross-node prompt disclosure in the service privacy policy. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (118)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description presents an LLM inference/routing service with pricing, model support, energy-aware routing, and onchain attestations. The supplied code does not implement inference, routing, model selection, API compatibility, blockchain attestations, or request handling. Instead, it is a client-side website UI script for nav/footer injection and status-dot updates. This is a materially different primary purpose, so the description does not accurately represent the code chunk's behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description presents a general-purpose inference platform: cheapest/greenest routing, 200+ models, OpenAI-compatible API, and onchain attestations. This code chunk does not implement such a service. Instead, it is a specific operational script for ACP protocol testing/graduation as a buyer. It requires an ACP wallet key, talks to hardcoded agent addresses, submits ten predefined prompts, pays for jobs, waits for negotiation/delivery phases, and evaluates the returned deliverables. While the prompts relate to energy/sustainability and the requirement includes mode='greenest', that is only a parameter in submitted job data, not evidence that this code itself performs spatial routing, model selection across 200+ models, or exposes an OpenAI-compatible interface. The actual primary purpose and capabilities are materially different from the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The core declared purpose is broadly represented: this route is indeed an OpenAI-compatible inference endpoint that performs spatial routing, factors in green/cheap modes, attaches energy-related metadata, supports multiple model selection, and queues onchain attestations on Base. However, the code also contains several substantial capabilities not disclosed in the description or permissions: it authenticates users via API keys or wallet sessions, checks and consumes free-tier quotas, requires and verifies payments (including onchain tx hashes and x402 protocol), settles billing, logs revenue, and caches responses. These are not merely incidental implementation details; billing/auth/payment handling is a major part of the endpoint’s behavior and materially expands what the skill does beyond simple routed inference. Therefore the description is incomplete enough to count as a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description is about LLM inference routing and energy/cost-aware model selection, but this code chunk does not perform any routing, model selection, inference, OpenAI-compatible API handling, or onchain attestation logic. Instead, it provides backend account infrastructure for API keys, quotas, balances, and privacy maintenance. While such functionality could support an inference platform, it is a materially different behavior from the declared primary purpose and introduces undeclared capabilities around credential management, billing state, and database persistence.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The supplied code does not implement model routing, energy-aware provider selection, OpenAI-compatible inference handling, access to 200+ models, or onchain attestations. Instead, it is a caching subsystem that stores and serves prior LLM responses from a local SQLite database keyed by prompt/model/user scope. While caching could be a supporting optimization for an inference platform, this chunk’s actual behavior is materially different from the declared primary purpose and introduces undeclared data storage/cache management capabilities.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description emphasizes spatial routing for LLM inference based on cost and green energy, broad model availability, OpenAI compatibility, and onchain attestations. None of those core behaviors appear in this code chunk. Instead, the code performs heuristic engagement scoring and model recommendation using request metadata and message characteristics. While model selection and cost savings are tangentially related to routing, the primary purpose here is not geographic/energy-aware routing or inference serving; it is engagement classification and simple auto-model choice. This is a material description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The code does not implement LLM inference routing, model selection, OpenAI-compatible serving, energy-aware routing, or onchain attestations. Instead, its primary purpose is payment processing: watching Base for ETH deposits and crediting internal API balances. This is a materially different function and introduces undeclared capabilities involving blockchain transaction monitoring, external price fetching, and database balance updates. Therefore the declared description does not accurately represent the supplied code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents an inference-routing platform focused on choosing the cheapest/greenest node and exposing 200+ models with OpenAI-compatible access and onchain attestations. This code chunk instead handles backend accounting/telemetry: it creates SQLite tables, tracks per-wallet free requests, logs request metadata, records revenue, and returns operational stats. While some fields like node_id, model, energy_price_kwh, carbon_intensity, and attestation_uid are consistent with the broader product domain, the actual behavior here is not routing inference requests or serving model APIs. These are materially different capabilities from the declared primary purpose and are undeclared persistence/analytics behaviors.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description is about LLM inference routing and pricing/energy optimization, with mention of onchain attestations. The supplied code does not perform inference routing, model selection, OpenAI-compatible API handling, energy-aware routing, pricing logic, or attestation generation/verification. Instead, it checks whether a wallet has an ERC-8004 identity token or a .base.eth basename and maps that to request allowances. While this uses Base onchain data, that is only loosely related to the description’s mention of onchain attestations and is not an implementation of the stated primary purpose. Therefore the code chunk’s actual behavior is materially different from the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The code's primary behavior is an OpenRouter API wrapper/proxy for chat completions with basic model-based pricing classification and optional streaming. It does not implement the key advertised capabilities of spatial routing, green-energy-aware routing, cheapest-route selection, or onchain attestations. While using OpenRouter may be broadly compatible with multi-model access, this specific chunk does not demonstrate those distinctive claims. Therefore the declared description materially overstates and misrepresents what this code actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description is about LLM inference routing and energy-aware model selection, but this code chunk does not perform any inference, routing, model selection, OpenAI-compatible API behavior, or attestation generation. Instead, it is a payment service focused on validating onchain ETH/USDC transfers on Base and checking wallet balances. While onchain payments could be part of a broader product, this specific code’s primary purpose is materially different from the declared skill description and introduces significant undeclared payment-processing behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The code chunk does not implement LLM inference routing, model selection, energy-aware routing, OpenAI-compatible inference, or onchain attestations. Its primary purpose is billing: selling prepaid API credits via Stripe and crediting balances to API keys after successful payment events. This is a materially different capability from the declared description, so the description does not accurately represent the code.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description is about LLM inference routing and model access, but the supplied code does not perform inference routing, model selection, OpenAI-compatible request handling, green-energy optimization, or onchain attestation generation. Instead, it implements payment infrastructure: a blockchain watcher that monitors USDC deposits on Base and updates API key balances in a database. This is a materially different primary purpose and includes undeclared capabilities related to blockchain monitoring, payment processing, and database mutation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The supplied code does not implement or indicate any LLM inference, routing, API compatibility, energy-aware optimization, or blockchain attestation behavior. It is purely a frontend styling configuration for Tailwind CSS. This is a materially different primary purpose from the declared description, so it is a clear mismatch.

Known Vulnerable Dependency: ws==8.18.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
97% confidence
Finding
The lockfile includes ws@8.18.0, which is flagged for uninitialized memory disclosure and memory-exhaustion DoS. In this skill's context, multiple packages rely on websocket functionality for blockchain/rpc/client communications, so if any server-side or long-lived websocket handling is exposed, an attacker could crash processes or potentially obtain unintended memory contents.

Known Vulnerable Dependency: js-cookie==3.0.1 — 1 advisory(ies): CVE-2026-46625 (JavaScript Cookie: Per-instance prototype hijack in assign() enables cookie-attr)

High
Category
Supply Chain
Confidence
80% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Hidden Instructions

High
Category
Prompt Injection
Content
<main id="main-content" class="flex-1 px-6 py-24">
  <div class="max-w-2xl mx-auto">

    <!-- Auth Section (shown when not logged in) -->
    <div id="auth-section" class="text-center">
      <h1 class="font-serif text-2xl font-bold text-warm-900 mb-2">Dashboard</h1>
      <p class="text-warm-500 mb-8">View your usage, savings, and environmental impact.</p>
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
<main id="main-content" class="flex-1 px-6 py-24">
  <div class="max-w-3xl mx-auto">

    <!-- ═══════════════════════════════════════════ -->
    <!--  FRENCH VERSION (version légale)            -->
    <!-- ═══════════════════════════════════════════ -->
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
<p class="mt-3">Conformément au Règlement Général sur la Protection des Données (RGPD) et à la loi Informatique et Libertés, vous disposez d'un droit d'accès, de rectification, de suppression et de portabilité de vos données. Pour exercer ces droits, contactez-nous à l'adresse indiquée ci-dessus.</p>
      </section>

      <!-- 5 — Propriété intellectuelle -->
      <section>
        <h2 class="font-serif text-xl font-semibold text-warm-900 mb-3">5. Propriété intellectuelle</h2>
        <p>L'ensemble des contenus présents sur ce site (textes, images, logiciels, marques, logos) est la propriété d'Ecofrontiers SARL, sauf mention contraire. Le logiciel et la marque Windfall sont la propriété d'Ecofrontiers SARL.</p>
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
<a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:bg-sage-600 focus:text-white focus:px-4 focus:py-2 focus:rounded focus:z-50">Skip to content</a>

<!-- Hero -->
<main id="main-content" class="hero-bg pt-32 pb-20 px-6">
  <div class="max-w-5xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-10 md:gap-14 items-start">
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
<!-- Right: terminal -->
    <div class="pt-2">
      <!-- Request: the 2-line switch -->
      <div class="terminal-chrome">
        <div class="terminal-bar">
          <span class="terminal-dot red"></span>
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
<p class="text-warm-500 text-center mb-10 max-w-xl mx-auto">Every request flows through four stages — from classification to verifiable proof.</p>

    <div class="grid grid-cols-1 md:grid-cols-2 gap-6 hiw-grid">
      <!-- Vertical connectors -->
      <span class="hiw-vline-left"></span>
      <span class="hiw-vline-right"></span>
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
</div>
</section>

<!-- Live Energy Routing -->
<section class="py-16 px-6">
  <div class="max-w-4xl mx-auto">
    <div class="text-center mb-10">
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
</div>
</section>

<!-- Scripts -->
<script src="/assets/shared.js" defer></script>
<script>
// Live oracle
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
<div class="prose-windfall space-y-8 text-warm-700 text-[15px] leading-relaxed">

      <!-- 1 -->
      <section>
        <h2 class="font-serif text-xl font-semibold text-warm-900 mb-3">1. Who we are</h2>
        <p>This privacy policy explains how <strong>Windfall</strong>, a product of <strong>Ecofrontiers SARL</strong>, collects, uses, and protects your data when you use the Windfall inference gateway at <a href="https://windfall.ecofrontiers.xyz" class="text-sage-600 hover:underline">windfall.ecofrontiers.xyz</a>.</p>
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/services/x402.ts:6