Back to skill

Security audit

Camofox Browser

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real browser automation skill, but it needs Review because it exposes powerful browser, session, cookie, and JavaScript controls with weak default containment.

Install only if you intentionally want an agent-controlled anti-detection browser. Keep the server bound to localhost or a private trusted network, do not expose port 9377 publicly, set strong CAMOFOX_API_KEY and CAMOFOX_ADMIN_KEY values, avoid importing cookies for sensitive accounts, restrict use of camofox_evaluate, and update or pin dependencies and browser artifacts before production deployment.

Vulnerability Patterns
  • 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
  • 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 (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
server.js:2597
Finding

Unauthenticated browser session management and cross-user session deletion

Content
View full analysis
{ try { const userId = normalizeUserId(req.params.userId); const session = sessions.get(userId); if (session) { await clearSessionDownloads(session); await session.context.close(); sessions.delete(userId); // Remove any lingering tab locks for the session for (const [listItemId, group] of session.tabGroups) { for (const tabId of group.keys()) { const lock = tabLocks.get(tabId); if (lock) { lock.drain(); tabLocks.delete(tabId); } } } refreshTabLockQueueDepth(); refreshActiveTabsGauge(); log('info', 'session closed', { userId }); } if (sessions.size === 0) scheduleBrowserIdleShutdown(); res.json({ ok: true }); } catch (err) { log('error', 'session close failed', { error: err.message }); handleRouteError(err, req, res); } }); ``` The server is started without an explicit loopback-only host: ```js const server = app.listen(PORT, async () => { ``` ### Technical Analysis The REST API treats request-supplied `userId` values as identities, but most routes do not authenticate the caller or verify that the caller owns the requested user, session, or tab. Only the cookie-import route and `/stop` have dedicated secret checks. In particular, `DELETE /sessions/:userId` accepts the target identity entirely from the URL and closes the associated browser context without authorization. The omission of a host argument in `app.listen` normally exposes the service on all available interfaces rather than restricting it to `127.0.0.1`. The same trust model affects tab creation, navigation, snapshots, screenshots, downloads, evaluation, and othe ...[truncated 1564 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
server.js:151
Finding

Server-side request forgery through unrestricted HTTP and HTTPS navigation

Content
View full analysis
page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 })); tabState.visitedUrls.add(url); } ``` ### Technical Analysis The URL validator restricts only the URI scheme. It does not reject destinations that resolve to: - IPv4 or IPv6 loopback addresses. - RFC1918 private networks. - Link-local networks. - Cloud instance metadata services. - Internal DNS names. - Localhost aliases. - Private addresses reached after an HTTP redirect. - Public hostnames that resolve or later rebind to internal addresses. Consequently, browser navigation can originate requests from the server's own network context. Because the API also exposes snapshots, screenshots, links, downloads, and page-context evaluation, an attacker may be able to retrieve or act upon the resulting internal response. ### Attack Path 1. The attacker reaches the browser API. 2. The attacker creates or navigates a tab to an internal target, for example: ```json { "userId": "attacker", "sessionKey": "ssrf", "url": "http://127.0.0.1:8080/admin" } ``` 3. `validateUrl` accepts the URL because its scheme is `http:`. 4. Playwright requests the destination from the browser server's host or ...[truncated 973 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
server.js:2518
Finding

Unauthenticated arbitrary JavaScript evaluation in browser page contexts

Content
View full analysis
{ try { const { userId, expression } = req.body; if (!userId) return res.status(400).json({ error: 'userId is required' }); if (!expression) return res.status(400).json({ error: 'expression is required' }); const session = sessions.get(normalizeUserId(userId)); const found = session && findTab(session, req.params.tabId); if (!found) return res.status(404).json({ error: 'Tab not found' }); session.lastAccess = Date.now(); const { tabState } = found; tabState.toolCalls++; tabState.consecutiveTimeouts = 0; const result = await tabState.page.evaluate(expression); log('info', 'evaluate', { reqId: req.reqId, tabId: req.params.tabId, userId, resultType: typeof result }); res.json({ ok: true, result }); } catch (err) { failuresTotal.labels(classifyError(err), 'evaluate').inc(); log('error', 'evaluate failed', { reqId: req.reqId, error: err.message }); res.status(500).json({ error: safeError(err) }); } }); ``` ### Technical Analysis The endpoint passes an attacker-supplied string directly to Playwright's `page.evaluate`. This executes arbitrary JavaScript in the origin and security context of the currently loaded page. Page-context execution is not equivalent to direct Node.js execution, because browser sandbox and same-origin restrictions still apply. Nevertheless, it provides powerful access to the active web application, including DOM content, JavaScript-visible storage, and authenticated same-origin APIs. The endpoint has no authentication or per-tab authorization beyond matching caller-supplied `userId` and `tabId`. The feature is explicitly exposed as a plugin tool for reading page st ...[truncated 1620 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
package.json:61
Finding

Automatic executable browser retrieval during package installation

Content
View full analysis
/dev/null 2>&1; then echo "Fetching Camoufox browser..." npx camoufox-js fetch fi ``` ### Technical Analysis A normal `npm install` automatically runs `npx camoufox-js fetch`, which retrieves a browser executable controlled by a third-party dependency and its upstream distribution infrastructure. The dependency uses a caret range (`^0.8.5`) rather than an exact version in `package.json`. Although the lockfile supplies integrity information for npm packages, the reviewed project code does not independently demonstrate checksum or signature validation for the browser artifact retrieved by the dependency CLI. The `|| true` suffix suppresses retrieval failures, reducing visibility into partial or unexpected installation states. Downloading a browser binary is functionally related to the declared browser-automation purpose, but automatically doing so during package installation unnecessarily expands the supply-chain trust boundary and executes network-enabled dependency code ...[truncated 1278 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (76)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
86% confidence
Finding

DELETE /sessions/:userId is a powerful destructive operation, and the documentation shows direct deletion keyed only by a user identifier with no mention of authorization, authentication, or confirmation. In a multi-user browser automation service, that creates a plausible avenue for cross-user denial of service and deletion of cookies/storage for other users if access controls are weak or absent.

Content

Scanner excerpt · AGENTS.md (reported line 115)May include surrounding context.

md
- `userId` isolates cookies/storage between users
- `sessionKey` groups tabs by conversation/task (legacy: `listItemId` also accepted)
- Sessions timeout after 30 minutes of inactivity
- Delete all user data: `DELETE /sessions/:userId`

## Running Engines

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The README explicitly instructs users to export browser cookies from Chrome/Firefox and use them for authenticated browsing. Cookies are bearer secrets; anyone with access to them can often hijack active sessions, bypass MFA already satisfied in the browser, and access sensitive accounts. In the context of an agent browser designed to automate web activity, this materially increases credential and account-takeover risk.

Content

Scanner excerpt · README.md (reported line 141)May include surrounding context.

md
**3. Export cookies from your browser:**

Install a browser extension that exports Netscape-format cookie files (e.g., "cookies.txt" for Chrome/Firefox). Export the cookies for the site you want to authenticate.

**4. Place the cookie file:**

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · README.md (reported line 141)May include surrounding context.

.jsonis stored in plaintext, so secrets don't belong there. SetCAMOFOX_API_KEY` in your shell profile, systemd unit, Docker env, or Fly.io secrets.

Cookie import is disabled by default. If CAMOFOX_API_KEY is not set, the server rejects all cookie requests with 403.

3. Export cookies from your browser:

Install a browser extension that exports Netscape-format cookie files (e.g., "cookies.txt" for Chrome/Firefox). Export the cookies for the site you want to authenticate.

4. Place the cookie file:

bash
mkdir -p ~/.camofox/cookies
cp ~/Downloads/linkedin_cookies.txt ~/.camofox/cookies/linkedin.txt

The default directory is ~/.camofox/cookies/. Override with CAMOFOX_COOKIES_DIR.

5. Ask your agent to import them:

Import my LinkedIn cookies from linkedin.txt

The agent calls camofox_import_cookies → reads the file → POSTs to the server with the Bearer token → cookies are injected into the browser session. Subsequent camofox_create_tab calls

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · AGENTS.md (reported line 84)May include surrounding context.

Close Tab

bash
DELETE /tabs/:tabId?userId=agent1

Search Macros

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

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

Close Tab

bash
DELETE /tabs/:tabId?userId=agent1

Search Macros

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
86% confidence
Finding

DELETE /sessions/:userId exposes a highly destructive action keyed directly by a user-controlled identifier, creating a plausible insecure direct object reference or parameter-abuse risk if the server trusts that path parameter. In this skill context, sessions contain cookies and storage isolation, so unauthorized deletion could disrupt users, destroy state, or erase stored browser data across tasks.

Content

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

md
- `userId` isolates cookies/storage between users
- `sessionKey` groups tabs by conversation/task (legacy: `listItemId` also accepted)
- Sessions timeout after 30 minutes of inactivity
- Delete all user data: `DELETE /sessions/:userId`

## Running Engines

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `server.js` - Camoufox engine (routes + browser logic only — NO `process.env` or `child_process`)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `server.js` - Camoufox engine (routes + browser logic only — NO `process.env` or `child_process`)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `server.js` - Camoufox engine (routes + browser logic only — NO `process.env` or `child_process`)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `lib/youtube.js` - YouTube transcript extraction via yt-dlp (`child_process` isolated here)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `lib/youtube.js` - YouTube transcript extraction via yt-dlp (`child_process` isolated here)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `lib/request-utils.js` - HTTP request classification helpers (`actionFromReq`, `classifyError`)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `lib/request-utils.js` - HTTP request classification helpers (`actionFromReq`, `classifyError`)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `lib/request-utils.js` - HTTP request classification helpers (`actionFromReq`, `classifyError`)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `lib/macros.js` - Search macro URL expansion

Known Vulnerable Dependency: @isaacs/brace-expansion==5.0.0 — 1 advisory(ies): CVE-2026-25547 (@isaacs/brace-expansion has Uncontrolled Resource Consumption)

High
Category
Supply Chain
Confidence
87% confidence
Finding

@isaacs/brace-expansion 5.0.0 is flagged for uncontrolled resource consumption, which can enable denial of service through crafted patterns. In this file it is a transitive dependency of glob/minimatch-style matching, so exploitability depends on whether untrusted input can influence pattern evaluation, but the vulnerable component is genuinely present.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: minimatch==3.1.2 — 3 advisory(ies): CVE-2026-27904 (minimatch ReDoS: nested *() extglobs generate catastrophically backtracking regu); CVE-2026-26996 (minimatch has a ReDoS via repeated wildcards with non-matching literal in patter); CVE-2026-27903 (minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja)

High
Category
Supply Chain
Confidence
93% confidence
Finding

minimatch 3.1.2 has multiple ReDoS advisories involving catastrophic backtracking on crafted glob patterns. Because this version appears multiple times in tooling and file-matching dependencies, any path that lets attackers influence glob expressions could cause excessive CPU usage and service degradation.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: adm-zip==0.5.16 — 2 advisory(ies): CVE-2026-76845 (adm-zip extraction follows destination symlinks, allowing arbitrary file overwri); CVE-2026-39244 (adm-zip: Crafted ZIP file triggers 4GB memory allocation)

High
Category
Supply Chain
Confidence
92% confidence
Finding

adm-zip 0.5.16 is reported vulnerable to both symlink-based overwrite during extraction and excessive memory allocation from crafted ZIP files. This is particularly relevant here because the package set includes automation/browser tooling that may download, unpack, or process archives, increasing the chance that archive handling is part of normal operation.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: brace-expansion==1.1.13 — 3 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro); CVE-2026-69152 (brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-1)

High
Category
Supply Chain
Confidence
90% confidence
Finding

brace-expansion 1.1.13 has several denial-of-service advisories caused by exponential or unbounded expansion behavior. As a transitive dependency used by older minimatch/glob chains in the tool stack, it represents a genuine resource-exhaustion risk when handling attacker-influenced patterns.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: browserslist==4.28.1 — 2 advisory(ies): CVE-2026-73088 (Browserslist: Uncaught crash / prototype write via untrusted browserslist-stats.); CVE-2026-73089 (Browserslist: Unbounded memory growth (no cache eviction) via distinct query res)

High
Category
Supply Chain
Confidence
84% confidence
Finding

browserslist 4.28.1 is flagged for crash/prototype-write and unbounded memory growth issues when processing untrusted stats or distinct query results. While often used in build tooling rather than request-time logic, it is still a real vulnerability in environments where attacker-controlled configuration or inputs can reach the package, such as CI pipelines or dynamic tooling services.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The camofox_evaluate tool exposes arbitrary JavaScript execution in the active page context. In an agent setting, prompt-influenced instructions or untrusted content could cause the agent to run scripts that exfiltrate page data, abuse authenticated sessions, manipulate DOM state invisibly, or invoke in-page APIs with the user's privileges.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The cookie import feature reads local cookie files and injects them into browser sessions, enabling session hijacking or reuse of authenticated identities. In this skill context, that is especially dangerous because the plugin is designed for anti-detection browsing and explicitly mentions authenticating to sites like LinkedIn without interactive login, which materially increases abuse potential.

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 · tests/unit/security.test.js (reported line 25)May include surrounding context.

js
test('blocks file:// URLs on tab creation', async () => {
      const client = createClient(serverUrl);
      try {
        await client.createTab('file:///etc/passwd');
        fail('Should have rejected file:// URL');
      } catch (err) {
        expect(err.status).toBe(400);

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/unit/security.test.js (reported line 65)May include surrounding context.

js
const client = createClient(serverUrl);
      try {
        const { tabId } = await client.createTab(`${testSiteUrl}/pageA`);
        await client.navigate(tabId, 'file:///etc/shadow');
        fail('Should have rejected file:// URL');
      } catch (err) {
        expect(err.status).toBe(400);

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill exposes browser automation primitives such as navigate, click, and type without warning that they may act on logged-in sessions, submit forms, make purchases, or send user-provided content to third-party sites. In an agent setting, omission of those warnings materially increases the risk of unsafe use and unintended external actions.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.