ZeroChat · Current code audit · 7.11.0

Code quality and infrastructure

Verified status, local security, and corrective work.

25 de septiembre de 2026 · dev · Codex (OpenAI)

← Back to architecture

Assessment

The 7.11.0 codebase is testable and modular at source level: 644 general tests and 71 browser tests pass in this review; npm run build rebuilds the backend without product diffs. Security and recovery limits remain open. No remote compromise or line coverage measurement is claimed.

1. Scope and method

Reviewed zerochat.html, js/, css/, py/, zerochat.py, sw.js, tests/, scripts/, and CI workflows. Claims in the 7.8.0 reports were checked against current code and tests. This is static inspection plus local testing, without a penetration test, live providers, every browser, or load testing.

Examined baseline: dev branch at 7.11.0. File references link to reviewed code.

2. Executed validation

CheckResultScope
npm test644/644, no failuresProject runner covering logic, integration, architecture, infrastructure, and browser tests.
npm run test:browser71/71, no failuresLocal Chromium and Playwright scenarios; several check page and console errors.
npm run buildPassedOrama and assembled backend; no generated product diff.

Provider tests largely use doubles and do not prove external API availability. Performance, branch coverage, screen reader accessibility, and end-to-end offline reliability were not measured.

3. Observed architecture

The web client is static HTML/CSS/JS. ChatState owns conversation state, ZeroChatDB handles IndexedDB, BaseProviderAdapter normalizes providers, and the tool contract defines registration and views. The backend is assembled from py/*.py, with zz-main.py last. Packaging metadata and smoke tests target a Python-only wheel; this review did not rebuild the wheel.

Large modules still raise maintenance costs: js/app.js exceeds 2,100 lines, js/file-parser.js 2,000, and js/agent-core.js 1,600. Size alone is not a defect; future changes should preserve responsibility boundaries and add focused regression tests.

4. Open findings

ID / priorityEvidence and impactRemedy and acceptance test
F2 · Highee-mcp.py checks edit_file.mode only as a string up to 32 characters, not against the enum declared in dd-tools.py. In edit_file, an unknown mode with content falls through to full-file write. An authenticated RPC call can overwrite a file due to a mode error.Reject modes outside surgical|write|append|replace_chunk before touching the file, including direct Python calls. Test via HTTP that an invalid mode leaves bytes and metadata unchanged.
Q1 · Highprofile-backup.js uses direct SHA-256 as password material and stores that reusable value in localStorage for up to 24 hours. Backups encrypted with the public default key offer limited secrecy; same-origin script access can recover cached material.Use a versioned salted KDF and migrate old backups; reduce or remove persistent caching. Test old-format decryption, wrong passwords, expiry, and cross-tab behavior.
Q2 · Mediumcc-environment.py keeps a daily server token in ~/zerochat/config/token.json without explicitly setting mode 0600. File confidentiality depends on umask; a same-day restart reuses the token.Create with owner-only permissions, check existing files, and decide whether to rotate per launch. Test a permissive umask and rejection of an old token after rotation.
Q3 · Mediumsw.js uses Promise.allSettled and suppresses download errors at install. An incomplete cache may activate although published-path routing tests pass.Define required assets and fail or retry install if missing. Test a failed critical fetch and offline reload under /zerochat/.
Q4 · Mediumtool-security.js applies R/W and approval rules in the browser. ff-server.py authenticates RPC but does not independently enforce those policies. A client holding a valid token can directly invoke local tools with the user's privileges.Document the trust model; if modified clients must be contained, enforce policy at the backend. Test a direct authenticated request outside an allowed folder and revocation.

Q4 is an architectural boundary, not a token-free exploit. The venv isolates Python dependencies, not shell or MCP operating system privileges.

5. Earlier findings and residual risk

F1, F3, and F4 from the 7.8.0 report should no longer be listed as open. F2 remains open, as shown above. Permission tests cover command prefixes with directory rules, relative paths, and shell aliases. read_file enforces a UTF-8 byte budget and edit_file declares a mode enum that the RPC validator does not enforce. Service Worker tests execute the handler for the published path. Coverage limits remain: precache tests do not simulate network failure.

HTML sinks, Markdown, tool cards, and URLs still need review when changed. Current utility and UI tests cover sanitization paths, but a textual search for innerHTML neither proves nor rules out XSS.

6. Code hygiene and boundaries

Searches covered native dialogs, obsolete tool fields, state outside ChatState, innerHTML sinks, event listeners, and translation keys. Architecture contracts and current tests cover dialogs, icons, declarative tools, state, and sanitization in specific paths. No code was labeled dead solely for lacking a static reference: UMD modules, dynamic registration, and HTML loading require runtime confirmation. No functional duplication was established strongly enough to recommend a broad extraction.

HTML review should focus on MCP results, document titles, and agent cards. ChatUtils supplies text and sanitization helpers; Markdown has its own boundary. Each changed view displaying external data should have an injection test using malicious text, URLs, and attributes.

7. Recommended sequence

  1. Fix F2 and add an HTTP regression test.
  2. Revise Q1 encryption and cache design with a compatible migration.
  3. Harden Q2 token creation and rotation.
  4. Choose Q4's trust boundary explicitly and add direct RPC tests.
  5. Make Q3 offline installation verifiable under partial failure.
  6. Keep browser and packaging gates in CI for promotions.

Module size alone does not justify a broad rewrite. Each fix needs a test reproducing the specific behavior.