An AI-native, privacy-first browser. Built to be driven by agents over MCP — you bring your own agent.
Drift inferred · capture-to-capture
No drift recorded — single capability capture; advisories appear once its surface changes.
transport http counts 15 tools · 0 res
· 0 prompts
permission surface via code analysis
tools
-
browser_act
-
browser_attach
-
browser_capture
-
browser_console
-
browser_container
-
browser_fill_form
-
browser_navigate
-
browser_profile
-
browser_read
-
browser_snapshot
-
browser_tabs
-
browser_theme
-
task_done
-
vault_entries_for_origin
-
vault_request_fill
prompt-surface
shipped agent-instruction files + hidden-content / dangerous-code findings —
quoted from the analyzed source
analyzed commit 0c36eed · analyzer v33 · 4w ago
danger signals1
- suspicious endpoint a.ngrok.io cunninghambe-aperture-0c36eed/test/security.test.ts :100
['https://a.ngrok.io', 'https://b.ngrok.io'],
evidence-backed
findings quoted directly from the published source artifact — not inferred
code files: 107
filesystem 28
- fs cunninghambe-aperture-0c36eed/bench/darkmode.mjs :36
import { readFileSync, readdirSync, statSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/bench/guards.mjs :55
import { readFileSync, readdirSync, statSync } from 'node:fs'; - fs (weak) cunninghambe-aperture-0c36eed/bench/headtohead/fixtures/make-fixtures.mjs :31
import { readFileSync, writeFileSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/bench/headtohead/h2h.mjs :40
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/bench/headtohead/lib/h2hStore.mjs :29
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/bench/headtohead/lib/proxy.mjs :37
import { readFile } from 'node:fs/promises'; - fs cunninghambe-aperture-0c36eed/bench/headtohead/lib/pwUpstream.mjs :18
import { createWriteStream, readFileSync } from 'node:fs'; - fs (weak) cunninghambe-aperture-0c36eed/bench/headtohead/lint-fixtures.mjs :43
import { existsSync, readFileSync, readdirSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/bench/lib/aperture.mjs :25
import { createWriteStream, existsSync, mkdirSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/bench/probes/webbotauth/headerorder.mjs :26
import { appendFileSync, readFileSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/bench/probes/webbotauth/probe.mjs :2
import { readFileSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/bench/size.mjs :76
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
show 16 more
- fs cunninghambe-aperture-0c36eed/bench/task.mjs :89
import { appendFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/bench/tokens.mjs :22
import { readFileSync } from 'node:fs'; - fs cunninghambe-aperture-0c36eed/build/afterPack.cjs :10
* ELECTRON_RUN_AS_NODE=1 Aperture.exe -e "require('fs').readFileSync(vault)" - fs cunninghambe-aperture-0c36eed/src/capture/capture.ts :1
import { writeFile, mkdir, readFile } from 'node:fs/promises'; - fs cunninghambe-aperture-0c36eed/src/main/index.ts :2
import { writeFile } from 'node:fs/promises'; - fs cunninghambe-aperture-0c36eed/src/net/botAuth.ts :2
import { mkdir, readFile, writeFile } from 'node:fs/promises'; - fs cunninghambe-aperture-0c36eed/src/privacy/blocker.ts :1
import { readFile, writeFile, mkdir } from 'node:fs/promises'; - fs cunninghambe-aperture-0c36eed/src/telemetry/reporter.ts :2
import { readFile, writeFile } from 'node:fs/promises'; - fs cunninghambe-aperture-0c36eed/src/vault/attachments.ts :1
import { readFile, writeFile, mkdir, stat, copyFile, rename } from 'node:fs/promises'; - fs cunninghambe-aperture-0c36eed/src/vault/profileStore.ts :1
import { readFile, writeFile, mkdir, rename } from 'node:fs/promises'; - fs cunninghambe-aperture-0c36eed/src/vault/vault.ts :1
import { readFile, writeFile, mkdir, rename } from 'node:fs/promises'; - fs (weak) cunninghambe-aperture-0c36eed/test/autocrop.test.ts :2
import { readFileSync, readdirSync, statSync } from 'node:fs'; - fs (weak) cunninghambe-aperture-0c36eed/test/docs.test.ts :2
import { readFileSync } from 'node:fs'; - fs (weak) cunninghambe-aperture-0c36eed/test/lib/source.ts :1
import { readFileSync, readdirSync, statSync } from 'node:fs'; - fs (weak) cunninghambe-aperture-0c36eed/test/urlsurfaces.test.ts :2
import { readFileSync, readdirSync, statSync } from 'node:fs'; - fs (weak) cunninghambe-aperture-0c36eed/test/vault.test.ts :1
import { mkdtempSync, rmSync } from 'node:fs';
shell / exec 4
- shell cunninghambe-aperture-0c36eed/bench/headtohead/lib/h2hStore.mjs :28
import { execFileSync } from 'node:child_process'; - shell cunninghambe-aperture-0c36eed/bench/lib/aperture.mjs :24
import { spawn } from 'node:child_process'; - shell cunninghambe-aperture-0c36eed/bench/size.mjs :74
import { spawn } from 'node:child_process'; - shell (weak) cunninghambe-aperture-0c36eed/test/typecheck.test.ts :1
import { execFile } from 'node:child_process';
network 24
- net cunninghambe-aperture-0c36eed/bench/darkmode.mjs :35
import { createServer } from 'node:http'; - net cunninghambe-aperture-0c36eed/bench/fidelity.mjs :91
const res = await fetch('http://127.0.0.1:8817/mcp', { - net (weak) cunninghambe-aperture-0c36eed/bench/fixtures/bench.js :37
fetch(ENDPOINT, { - net cunninghambe-aperture-0c36eed/bench/guards.mjs :197
res = await fetch('http://127.0.0.1:8817/mcp', { - net (weak) cunninghambe-aperture-0c36eed/bench/headtohead/fixtures/bench.js :37
fetch(ENDPOINT, { - net cunninghambe-aperture-0c36eed/bench/headtohead/h2h.mjs :38
import { createServer } from 'node:http'; - net cunninghambe-aperture-0c36eed/bench/headtohead/lib/proxy.mjs :35
import { createServer } from 'node:http'; - net cunninghambe-aperture-0c36eed/bench/lib/aperture.mjs :45
await fetch(`http://127.0.0.1:${port}/`, { method: 'GET', signal: AbortSignal.timeout(700) }); - net cunninghambe-aperture-0c36eed/bench/lib/collector.mjs :9
import { createServer } from 'node:http'; - net cunninghambe-aperture-0c36eed/bench/lib/proxy.mjs :34
import { createServer } from 'node:http'; - net cunninghambe-aperture-0c36eed/bench/live.mjs :35
const res = await fetch(ENDPOINT, { - net cunninghambe-aperture-0c36eed/bench/probes/webbotauth/headerorder.mjs :25
import { createServer } from 'node:http';
show 12 more
- net cunninghambe-aperture-0c36eed/bench/size.mjs :73
import { createServer } from 'node:http'; - net (weak) cunninghambe-aperture-0c36eed/bench/size/fixtures/bench.js :37
fetch(ENDPOINT, { - net cunninghambe-aperture-0c36eed/bench/task.mjs :87
import { createServer } from 'node:http'; - net cunninghambe-aperture-0c36eed/src/capture/notion.ts :48
const create = await fetch(`${API}/file_uploads`, { - net cunninghambe-aperture-0c36eed/src/main/tabs.ts :492
// an origin's own CSP (`connect-src 'self'`) can forbid its `fetch()` and - net cunninghambe-aperture-0c36eed/src/main/vaultWindow.ts :255
const res = await fetch('https://api.notion.com/v1/users/me', { - net cunninghambe-aperture-0c36eed/src/mcp/server.ts :1
import { createServer, type Server as HttpServer } from 'node:http'; - net cunninghambe-aperture-0c36eed/src/net/botAuthCore.ts :591
// by calling `fetch()`. - net cunninghambe-aperture-0c36eed/src/privacy/containers.ts :125
// that can start a download can already `fetch()` the same bytes. What is - net (weak) cunninghambe-aperture-0c36eed/test/benchReport.test.ts :2
import { createServer } from 'node:http'; - net (weak) cunninghambe-aperture-0c36eed/test/botauth.test.ts :409
// re-opens the fetch() minting oracle S2 closes. Enumerating every value - net (weak) cunninghambe-aperture-0c36eed/test/egress.test.ts :22
* its `fetch()` and forbade nothing here. Aperture was a CSP bypass.
secrets 1
- secrets cunninghambe-aperture-0c36eed/bench/authprobe.mjs :21
console.log('ANTHROPIC_API_KEY in child env:', JSON.stringify(process.env.ANTHROPIC_API_KEY));
tool registrations 17
- browser_act cunninghambe-aperture-0c36eed/bench/lib/proxy.mjs :438
- browser_snapshot cunninghambe-aperture-0c36eed/bench/lib/proxy.mjs :455
- task_done cunninghambe-aperture-0c36eed/bench/lib/proxy.mjs :470
- browser_tabs cunninghambe-aperture-0c36eed/src/mcp/tools.ts :552
- browser_navigate cunninghambe-aperture-0c36eed/src/mcp/tools.ts :636
- browser_snapshot cunninghambe-aperture-0c36eed/src/mcp/tools.ts :714
- browser_read cunninghambe-aperture-0c36eed/src/mcp/tools.ts :762
- browser_container cunninghambe-aperture-0c36eed/src/mcp/tools.ts :856
- vault_entries_for_origin cunninghambe-aperture-0c36eed/src/mcp/tools.ts :892
- vault_request_fill cunninghambe-aperture-0c36eed/src/mcp/tools.ts :941
- browser_act cunninghambe-aperture-0c36eed/src/mcp/tools.ts :1301
- browser_fill_form cunninghambe-aperture-0c36eed/src/mcp/tools.ts :1826
show 5 more
- browser_profile cunninghambe-aperture-0c36eed/src/mcp/tools.ts :2115
- browser_attach cunninghambe-aperture-0c36eed/src/mcp/tools.ts :2138
- browser_theme cunninghambe-aperture-0c36eed/src/mcp/tools.ts :2199
- browser_capture cunninghambe-aperture-0c36eed/src/mcp/tools.ts :2241
- browser_console cunninghambe-aperture-0c36eed/src/mcp/tools.ts :2405
install hooks 1
- postinstall (suspicious) cunninghambe-aperture-0c36eed/bench/headtohead/package.json :8
node -e "console.log('pw mcp:', require('@playwright/mcp/package.json').version)"
declared dependencies 17
- @modelcontextprotocol/node@^2.0.0
- @modelcontextprotocol/server@^2.0.0
- @cfworker/json-schema@^4.1.1
- @ghostery/adblocker-electron@^2.18.1
- libsodium-wrappers-sumo@^0.8.4
- tldts@^7.4.10
- zod@^4.4.3
- @anthropic-ai/claude-agent-sdk@^0.3.220
- @electron/fuses@^2.1.3
- @types/libsodium-wrappers-sumo@^0.7.8
- @types/node@^24.0.0
- electron@^43.2.0
show 5 more
- electron-builder@^26.15.3
- electron-vite@^5.0.0
- typescript@^5.9.0
- vite@^7.0.0
- vitest@^3.2.0