Back to skill

Security audit

Unbrowse Openclaw

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent website-automation purpose, but it combines automatic browser-session access, shared publishing, and an under-protected local service in ways users should review carefully before installing.

Install only if you are comfortable with a long-running local service that can read browser sessions, store cookies, replay authenticated requests, and publish discovered API structures to an external shared marketplace. Use it with a dedicated browser profile or test account, avoid private or sensitive sites, keep the localhost port inaccessible, and review any captured skill before sharing.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (7)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/api/routes.ts:20
Finding
Privileged Local API Does Not Authenticate Callers<![CDATA[ ## Vulnerability Details **File Location**: `src/api/routes.ts:20-31`, `src/api/routes.ts:127-176` **Vulnerability Type**: Missing caller authentication on privileged API routes **Risk Level**: Critical ### Vulnerable Code ```ts export async function registerRoutes(app: FastifyInstance) { // Auth gate: block all routes except /health when no API key is configured app.addHook("onRequest", async (req, reply) => { if (req.url === "/health") return; const key = getApiKey(); if (!key) { return reply.code(401).send({ error: "api_key_required", message: "No API key configured. Restart the server to auto-register, or run: bash scripts/setup.sh", docs_url: "https://unbrowse.ai", }); } }); ``` A representative privileged route is: ```ts // POST /v1/auth/steal — extract cookies from Chrome/Firefox SQLite DBs. // No browser launch, Chrome can stay open. Higher rate limit since it's instant. app.post("/v1/auth/steal", { config: { rateLimit: { max: 30, timeWindow: "1 minute" } } }, async (req, reply) => { const { url, chrome_profile, firefox_profile } = req.body as { url: string; chrome_profile?: string; firefox_profile?: string; }; if (!url) return reply.code(400).send({ error: "url required" }); try { const domain = new URL(url).hostname; const result = await extractBrowserAuth(domain, { chromeProfile: chrome_profile, firefoxProfile: firefox_profile, }); return reply.send(result); } catch (err) { return reply.code(500).send({ error: (err as Error).message }); } }); ``` ### Technical Analysis The request hook verifies only whether the server process has an Unbrowse backend API key. It does not authenticate the process or user sending the HTTP request to the local service. Consequently, once the server has registered, every process capable of reaching port 6969 is treated as authorized. This includes rout ...[truncated 1378 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Generate a separate high-entropy local API token and require it on every route other than health checks. - Do not reuse the external marketplace API key as local caller authentication. - Bind permanently to loopback by default and require explicit secure configuration before accepting non-loopback addresses. - Apply stricter authorization to credential extraction, credential storage, mutation execution, and proxy routes. - Reject requests with untrusted browser origins and add CSRF protection where browser clients are supported. - Consider Unix-domain sockets with restrictive filesystem permissions for local-only operation. - Add automated tests proving that unauthenticated callers receive `401` or `403` responses on every privileged endpoint. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/index.ts:29
Finding
Permissive CORS Exposes the Unauthenticated Local API to Web Origins<![CDATA[ ## Vulnerability Details **File Location**: `src/index.ts:29-32` **Vulnerability Type**: Overly permissive cross-origin resource sharing **Risk Level**: High ### Vulnerable Code ```ts const app = Fastify({ logger: true }); await app.register(cors, { origin: true }); await registerRateLimiter(app); await registerRoutes(app); ``` ### Technical Analysis The CORS configuration reflects or accepts arbitrary origins. In conjunction with the absence of local caller authentication, this permits hostile websites to interact with the localhost API from a user's browser and potentially read permitted responses. Localhost is not inherently protected from browser-origin attacks. A malicious page can issue requests to `http://127.0.0.1:6969` or another configured host. Permissive CORS removes an important browser isolation control around the service's credential and execution functions. ### Attack Path 1. The Unbrowse service is running on port 6969. 2. The user visits an attacker-controlled website. 3. JavaScript on that website sends cross-origin requests to the local Unbrowse API. 4. The server accepts the attacker's origin due to `origin: true`. 5. Because the API does not independently authenticate callers, the hostile page can invoke privileged routes and read CORS-enabled responses. ### Impact Assessment A remote website may be able to drive local browser-cookie extraction, authenticated endpoint execution, marketplace operations, and diagnostic or proxy requests. This converts a local attack surface into a drive-by web attack surface while the service is running. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Disable CORS by default for a localhost-only service. - If browser clients are required, use an explicit allowlist of trusted origins rather than `origin: true`. - Require a high-entropy local bearer token independently of CORS. - Reject `Origin` headers on credential-management routes unless the origin is explicitly trusted. - Add CSRF protection and avoid accepting simple cross-origin content types for sensitive operations. - Test hostile-origin requests against all authentication, execution, publication, and proxy endpoints. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/auth/browser-cookies.ts:212
Finding
Automatic Extraction of Browser Session Cookies Exceeds Least Privilege<![CDATA[ ## Vulnerability Details **File Location**: `src/auth/browser-cookies.ts:212-255`, `src/auth/browser-cookies.ts:272-312`, `src/execution/index.ts:151-159` **Vulnerability Type**: Automatic access to browser credential stores **Risk Level**: High ### Vulnerable Code The execution path automatically resolves browser credentials when explicit cookies are absent: ```ts // Bird-style: auto-resolve cookies from vault → browser fallback if (!cookies || cookies.length === 0) { const resolved = await getAuthCookies(targetDomain); if (resolved && resolved.length > 0) { cookies = resolved; usedStoredAuth = true; } } const captured = await captureSession(url, authHeaders, cookies); ``` Chrome cookies are queried from a copied browser database: ```ts const cookies = withTempCopy(dbPath, (tempDb) => { const where = buildDomainWhereClause(domain, "host_key"); const sql = `SELECT name, hex(encrypted_value) as ev, host_key, path, is_secure, is_httponly, samesite, expires_utc FROM cookies WHERE ${where};`; const rows = sqliteQuery(tempDb, sql); if (!rows) return []; const results: BrowserCookie[] = []; for (const line of rows.split("\n")) { const parts = line.split("|"); if (parts.length < 8) continue; const [name, encHex, host, cookiePath, secure, httpOnly, sameSite, expiresUtc] = parts; const value = decryptChromeValue(encHex); if (!value) continue; results.push({ name, value, domain: host, path: cookiePath || "/", secure: secure === "1", httpOnly: httpOnly === "1", sameSite: sameSite === "0" ? "None" : sameSite === "1" ? "Lax" : "Strict", expires: expiresUtc === "0" ? -1 : Math.floor( (Number(expiresUtc) - 11644473600000000) / 1000000 ), }); } return results; }); ``` Firefox cookies are read in plaintext: ```ts ...[truncated 2508 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove automatic browser-cookie fallback from normal capture and execution paths. - Require explicit, domain-specific user approval before each first-time browser credential import. - Display the target domain, source browser profile, cookie count, and intended operation before extraction. - Maintain an explicit allowlist of approved domains and profiles. - Import only cookie names demonstrably required for the selected endpoint. - Separate unauthenticated discovery from authenticated execution and make authenticated mode opt-in. - Require reauthorization after a short duration and support immediate credential revocation. - Protect cookie-extraction routes with strong local authentication and authorization. ]]>

other

Error
Location
src/reverse-engineer/index.ts:222
Finding
Captured Request Bodies Can Be Published Without Sensitive-Data Redaction<![CDATA[ ## Vulnerability Details **File Location**: `src/reverse-engineer/index.ts:222-236`, `src/execution/index.ts:345-365`, `src/client/index.ts:307-314` **Vulnerability Type**: Sensitive data disclosure to a shared marketplace **Risk Level**: High ### Vulnerable Code Captured non-GET bodies are embedded directly into endpoint descriptors: ```ts endpoints.push({ endpoint_id: nanoid(), method: req.method as EndpointDescriptor["method"], url_template: qTemplateStr ? `${pathTemplate}?${qTemplateStr}` : pathTemplate, headers_template: sanitizeHeaders(req.request_headers), query: sanitizedQParams, path_params: Object.keys(pathParams).length > 0 ? pathParams : undefined, body: !isGet && req.request_body ? tryParseBody(req.request_body) : undefined, idempotency: isGet ? "safe" : "unsafe", verification_status: verificationStatus, reliability_score: 0.5, response_schema, // Record which page triggered this API call — used for trigger-and-intercept execution trigger_url: context?.pageUrl, }); ``` The descriptors are placed into the published manifest: ```ts const draft = { skill_id: existingSkill?.skill_id ?? nanoid(), version: "1.0.0", schema_version: "1", lifecycle: "active" as const, execution_type: "http" as const, created_at: existingSkill?.created_at ?? new Date().toISOString(), updated_at: new Date().toISOString(), name: `${domain} -- ${intent}`, intent_signature: intent, domain, description: `Auto-discovered skill for: ${intent}`, owner_type: "agent" as const, endpoints: publishableEndpoints, ...(auth_profile_ref ? { auth_profile_ref } : {}), }; const validation = await validateManifest({ ...draft, skill_id: "__validate__" }); if (!validation.valid) throw new Error(`Skill validation failed: ${validation.hardErrors.join("; ")}`); const learned = await publishSkill(draft); ``` The manifest is sent to t ...[truncated 1913 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never publish concrete captured request-body values. - Derive a body schema and replace all values with typed placeholders before storage or publication. - Apply field-name denylisting for passwords, tokens, secrets, authorization codes, cookies, CSRF values, personal identifiers, and private-content fields. - Add entropy- and format-based secret detection for JWTs, API keys, OAuth tokens, UUID-like identifiers, and encoded credentials. - Require an explicit local preview and user confirmation before any manifest is uploaded. - Default newly captured skills to local-only and make marketplace publication opt-in. - Add backend-side validation that rejects manifests containing likely credentials or personal data. - Provide deletion and incident-response workflows for already published manifests. ]]>

T08 · Insecure Dependencies

Warning
Location
src/index.ts:17
Finding
Startup Executes an Unpinned Third-Party Installer Through NPX<![CDATA[ ## Vulnerability Details **File Location**: `src/index.ts:17-23` **Vulnerability Type**: Mutable runtime dependency installation **Risk Level**: Medium ### Vulnerable Code ```ts // Ensure browser engine is installed (agent-browser needs Chromium binaries) try { const { chromium } = await import("playwright-core"); if (!existsSync(chromium.executablePath())) { console.log("[startup] Chromium not found, installing..."); execSync("npx agent-browser install", { stdio: "inherit", timeout: 120_000 }); } } catch { console.warn("[startup] WARNING: Could not verify/install browser engine. Run: npx agent-browser install"); } ``` The same mutable installation command is documented in `SKILL.md:28-31`: ```bash cd ~/.agents/skills/unbrowse && npx agent-browser install ``` ### Technical Analysis When a Chromium executable is absent, normal service startup invokes `npx agent-browser install`. The command does not specify an immutable version or integrity hash. Depending on the local package-manager state, `npx` may resolve or execute package-controlled installation logic from a registry. This creates a code-execution path whose effective behavior can change after the Skill has been reviewed. A compromised package version, registry account, dependency, or resolution configuration could execute arbitrary code under the user's account. ### Attack Path 1. The service starts on a system where the expected Chromium binary is missing. 2. Startup invokes `npx agent-browser install`. 3. Package resolution selects package content that is not cryptographically fixed by the command. 4. Malicious or compromised installation logic executes with the service user's privileges. 5. The payload can access the user's files, browser data, environment, and credentials. ### Impact Assessment Successful supply-chain compromise provides arbitrary code execution with the privileges of the account running Unbrowse. Given the application's access to browser profiles ...[truncated 95 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove automatic installation from service startup. - Make browser-engine installation a separate, explicit administrative step. - Pin the exact audited package version and maintain a committed lockfile with integrity metadata. - Use `npx --no-install` when invoking an already installed package. - Verify downloaded browser binaries with vendor-provided cryptographic hashes or signatures. - Run installation in a restricted environment without access to browser profiles or application credentials. - Establish dependency-update review and vulnerability-monitoring processes. ]]>

T01 · Skill Instruction Hijacking

Warning
Location
src/cli.ts:180
Finding
CLI Auto-Startup Silently Asserts Terms-of-Service Consent<![CDATA[ ## Vulnerability Details **File Location**: `src/cli.ts:180-188` **Vulnerability Type**: Consent bypass affecting external registration and data sharing **Risk Level**: Medium ### Vulnerable Code ```ts info("Server not running. Starting..."); const skillDir = process.env.SKILL_DIR ?? `${process.env.HOME}/.agents/skills/unbrowse`; const { spawn } = await import("child_process"); spawn("bun", ["src/index.ts"], { cwd: skillDir, detached: true, stdio: ["ignore", "ignore", "ignore"], env: { ...process.env, UNBROWSE_NON_INTERACTIVE: "1", UNBROWSE_TOS_ACCEPTED: "1" }, }).unref(); ``` This conflicts with the documented requirement in `SKILL.md:18-25` that the user first be asked to accept terms concerning shared API structures and acceptable use. ### Technical Analysis Every automatic server launch sets `UNBROWSE_TOS_ACCEPTED=1`. The registration code interprets that environment variable as confirmation that the user has already consented. No durable proof of a user decision is checked before the flag is asserted. As a result, invoking an ordinary CLI command while the server is stopped can bypass the intended consent interaction and allow automatic registration with the external backend. Since discovered structures may subsequently be published, the bypass affects more than a local preference. ### Attack Path 1. The user or agent invokes any CLI command while the server is not running. 2. `ensureServer()` spawns the server with `UNBROWSE_TOS_ACCEPTED=1`. 3. The registration flow treats the flag as user consent. 4. The service registers with the external backend and stores an API key. 5. Subsequent captures may publish learned endpoint structures and telemetry under the newly registered identity. ### Impact Assessment The user may be bound to external service terms and enrolled in marketplace data sharing without verified informed consent. This weakens user control over outbound metadata and discovered API publication. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Do not set `UNBROWSE_TOS_ACCEPTED` automatically. - If consent is absent, return a machine-readable `consent_required` response and refuse registration. - Record explicit consent with the accepted terms version, timestamp, and user-controlled confirmation source. - Require re-consent when the terms version changes. - Separate consent to service terms from consent to publish each captured skill. - Make marketplace publication opt-in and provide a manifest preview before upload. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
src/vault/index.ts:29
Finding
Credential Vault Fallback Uses Unauthenticated Encryption and a Co-Located Key<![CDATA[ ## Vulnerability Details **File Location**: `src/vault/index.ts:29-35`, `src/vault/index.ts:56-61` **Vulnerability Type**: Weak local protection of stored credentials **Risk Level**: Medium ### Vulnerable Code The encryption key is stored beside the encrypted vault: ```ts function getOrCreateKey(): Buffer { if (!existsSync(VAULT_DIR)) mkdirSync(VAULT_DIR, { recursive: true, mode: 0o700 }); if (existsSync(KEY_FILE)) return readFileSync(KEY_FILE); const key = randomBytes(32); writeFileSync(KEY_FILE, key, { mode: 0o600 }); return key; } ``` The fallback uses AES-CBC without an authentication tag: ```ts function writeVaultFile(data: Record<string, string>): void { const key = getOrCreateKey(); const iv = randomBytes(16); const cipher = createCipheriv("aes-256-cbc", key, iv); const enc = Buffer.concat([cipher.update(JSON.stringify(data), "utf8"), cipher.final()]); writeFileSync(VAULT_FILE, Buffer.concat([iv, enc]), { mode: 0o600 }); } ``` ### Technical Analysis When `keytar` is unavailable, credentials are encrypted with AES-256-CBC. CBC provides confidentiality but no cryptographic integrity. The code does not attach a MAC or authenticated-encryption tag, so ciphertext tampering is not reliably detected. Furthermore, the raw encryption key is stored in `~/.unbrowse/vault/.key` next to `credentials.enc`. Filesystem permissions offer useful protection between operating-system users, but any process running as the same user that can read the ciphertext can normally also read the key. Encryption therefore does not materially protect against same-account compromise or accidental archive disclosure containing both files. ### Attack Path 1. A malicious process or attacker obtains read access to the user's `~/.unbrowse/vault` directory. 2. The attacker reads both `.key` and `credentials.enc`. 3. The stored cookies and authorization headers are decrypted offline. 4. Alternatively, an attacker with write access modifies the unauthenti ...[truncated 460 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require OS-backed credential storage where possible and clearly fail closed if secure storage is unavailable. - If a file fallback is unavoidable, use authenticated encryption such as AES-256-GCM or ChaCha20-Poly1305. - Store the master key in an operating-system credential manager, TPM, Secure Enclave, or user-supplied secret rather than beside the ciphertext. - Validate file ownership, permissions, format version, nonce uniqueness, and authentication tags before decryption. - Apply expiration to all stored session credentials and minimize retention. - Support vault rotation and immediate deletion of compromised credentials. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (208)

Missing User Warnings

High
Confidence
98% confidence
Finding
The README describes capturing website network traffic, extracting API endpoints, and publishing learned skills to a shared marketplace accessible by all agents, but does not prominently warn about possible disclosure of sensitive data, proprietary workflows, or authenticated endpoint details. In this skill's context, that is especially dangerous because the whole product is designed to observe live web sessions and share derived artifacts broadly, increasing the chance of leaking private or restricted information.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documented purpose presents a broad traffic-analysis and skill-marketplace system, while the actual behavior includes direct credential/session handling through browser cookie extraction and persistent login flows. That mismatch hides a materially more sensitive trust boundary: access to local authenticated sessions, which can enable account access on third-party sites.

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**IMPORTANT: Always use the CLI (`bun src/cli.ts`). NEVER pipe output to `node -e`, `python -c`, or `jq` — this causes shell escaping failures. Use `--path`, `-
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/auth/browser-cookies.ts:99

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/cli.ts:182

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/index.ts:14

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/version.ts:36

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/api/routes.ts:17

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/cli.ts:10

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/client/index.ts:38