Skip to content

Security

Edgar Cano edited this page Oct 12, 2026 · 6 revisions

Security

Reporting vulnerabilities

Do not open a public issue.

Report via GitHub Security Advisories with:

  • A description of the vulnerability
  • Reproduction steps
  • Affected versions (if known)

Response times are a future goal, not a committed SLA at this time.

Security model

3va's security model is built around three principles:

1. Deny by default

No access to the filesystem, network, environment variables, or child processes unless explicitly granted via a flag — and that applies uniformly to application code and to every dependency it pulls in. See Permissions for the capability model, including package.json grants and per-dependency scoping.

2. Untrusted dependencies

The package manager treats packages as untrusted code. Lifecycle scripts (preinstall, install, postinstall) are blocked by default — the single escape hatch is opting out per-invocation with 3VA_ALLOW_SCRIPTS=1, which re-enables exactly the class of attack the deny-by-default model exists to close.

Install-time supply-chain checks:

  • Tarball integrity — SHA-256/SHA-512 verification
  • Dependency-confusion protection — .npmrc-pinned scopes never fall back to public registries
  • Typosquatting detection — edit-distance check against a popular-packages list
  • Automatic per-tarball malware gate — aborts the install on high-severity findings

The 3va audit command adds a fuller picture:

  • Known malicious patterns (static analysis)
  • CVEs via the OSV database (24-hour cache)
  • Leaked secrets and credentials (opt-in with --secrets)

The full audit is not automatic on install — only the per-tarball malware gate is. Run 3va audit --secrets yourself after adding dependencies. See Package Manager and Roadmap.

3. Post-quantum cryptography

The vvva_crypto crate uses NIST-standardized post-quantum primitives:

  • ML-KEM-768 for key encapsulation
  • ML-DSA for digital signatures

tls.pqConnect(port, host[, options]) (needs --allow-net=<host>) performs a real in-handshake hybrid X25519MLKEM768 key exchange inside TLS 1.3 (RFC 10024); check socket.pqNegotiated / socket.negotiatedGroup to see whether the server agreed. https.createServer() offers the same group to clients since 2.12. See Roadmap.

4. Host-key verification (SSH)

ssh2.Client.connect() verifies the server key and fails closed (EHOSTUNVERIFY). A connection needs hostFingerprint (a SHA256:… fingerprint), knownHosts (an OpenSSH known_hosts file, read through the --allow-read permission model) or hostVerifier (a callback returning exactly true to accept). A connect that passes none of these is trusted only on loopback or under --allow-insecure; an explicit option is enforced there too. A known_hosts entry whose key changed is refused.

5. HTTP-layer protection

A built-in firewall (vvva_firewall) operates in the connection-accept loop before any byte reaches JavaScript: per-IP rate and connection limits, Slowloris/RUDY deadlines, adaptive auto-block escalation for repeat offenders, and a request-smuggling guard. See HTTP Performance.

Automated security checks

Every commit and PR is scanned by:

  • Semgrep SAST — custom rules in .semgrep/rules/ covering unsafe Rust patterns, filesystem access, and 3va-specific security properties
  • CodeQL — GitHub's semantic code analysis
  • Gitleaks — secret scanning
  • cargo-audit — Rust dependency CVE scanning
  • cargo-deny — dependency license and ban enforcement

Known residual gaps

Honest accounting of what's still open:

  • npm provenance verification (opt-in --require-provenance) checks the Sigstore DSSE signature and in-toto subject but does not yet validate the Fulcio certificate chain to its root or Rekor inclusion proofs.
  • Package-scoped permission enforcement wraps plain factory functions only — a PascalCase constructor like net.Socket is deliberately left unwrapped (wrapping it would break instanceof), so new require('net').Socket() followed by .connect() bypasses scoping. See Permissions.
  • 3va permissions suggest/learn don't yet write into package.json.

See Roadmap for the full list.

Responsible disclosure

We follow coordinated disclosure. If you discover a vulnerability, please give us reasonable time to address it before public disclosure. No fixed timeline has been committed to at this time.

Clone this wiki locally