Skip to content

PR-5: Security trio — archive hardening, license-secret hygiene, bind warning + client token sync - #31

Merged
utkuvibing merged 3 commits into
mainfrom
chore/pr5-security-trio
Sep 4, 2026
Merged

PR-5: Security trio — archive hardening, license-secret hygiene, bind warning + client token sync#31
utkuvibing merged 3 commits into
mainfrom
chore/pr5-security-trio

Conversation

@utkuvibing

Copy link
Copy Markdown
Owner

PR-5 — Security trio (Phase 0)

Three independent, individually revertable commits. No science changes, no enforcement changes.

Track A — archive extraction hardening + failure-atomic install

  • New core/archive_safety.py: OS-independent lexical validation (POSIX absolutes, drive-qualified/rooted/UNC Windows paths, .. across both separators, NULs) + resolved containment check; ZIP symlink rejection; TAR allow-list of regular files/directories only. Manual checks instead of tarfile filter="data" (3.11 floor).
  • tools/library_ingest/common.py and core/reference_library._install_package use it.
  • _install_package rewritten as validate→stage→backup→promote→cleanup: a hostile/corrupt replacement raises before the working install is touched, and a failed promotion restores the previous install from backup. Install-level ValueError still aborts sync(), exactly like hash mismatches.
  • Cached archive_path bytes are written only after the new payload passes validation. Not claimed: crash-atomicity across process kill, or archive-bytes/extracted-tree transactional coupling.

Track B — license-secret resolution hygiene (no crypto claims)

  • Existing precedence extracted into _resolve_license_secret() with byte-identical behavior; no signature or caller changes.
  • Caveat, stated in code: the repository default is demo-only and publicly forgeable; commercial deployments MUST set MATERIALSCOPE_LICENSE_SECRET externally; changing the secret invalidates existing HMAC-signed licenses (re-issue required). Real distributable licensing should migrate to asymmetric signing (Ed25519/RSA, public verification key only) — explicitly deferred, roadmap PR-7 owns docs truth.

Track C — bind warning + bundled-client token sync (no enforcement)

  • New non_loopback_bind_warning() (ipaddress.is_loopback + localhost fallback, fail-safe on empty host) printed at startup by both dash_app.server and backend.main.
  • Open-by-default container behavior intentionally preserved: no auth enforcement, no generated token, /health stays unauthenticated (Docker HEALTHCHECK depends on it).
  • Fixed a real desync this work would otherwise ship: server --token X feeds backend auth while the co-located Dash client read its token once at import. Now the explicit server token overwrites a stale MATERIALSCOPE_API_TOKEN (explicit wins), and the client resolves the token per call. Server auth is still controlled only by --token/api_token.

Verification (local)

  • ruff check . → clean
  • python -m pytest tests/ -q1221 passed / 10 skipped (baseline 1184/10 at Replace legacy ASGI-to-WSGI bridge with native Dash FastAPI backend #28; delta is exactly the 37 new tests, zero regressions)
  • New: tests/test_archive_extraction_safety.py (23), tests/test_container_bind_warning.py (7); extended test_license_manager.py, test_dash_fastapi_backend.py (token-wins, import-order independence, open contract, /health).

Commits

  1. feat: harden archive extraction with rollback-capable library install
  2. chore: centralize license-secret resolution with honest forgeability docs
  3. feat: warn on unauthenticated non-loopback bind and sync bundled client token

Validate every zip/tar member (OS-independent traversal, link and device rejection) via shared core/archive_safety; ingest and library install use it. _install_package stages, backups, and swaps so a failed replacement restores the working install. Install ValueError still aborts sync.
…docs

Extract the existing explicit/env/legacy/default precedence into _resolve_license_secret; no behavior change. Docstrings state the repo default is publicly forgeable demo-only, commercial builds must inject MATERIALSCOPE_LICENSE_SECRET, rotation requires re-issuance, and real distributable licensing wants asymmetric signing (deferred).
…nt token

Explicit --token/api_token stays the sole server-auth source and now overwrites a stale MATERIALSCOPE_API_TOKEN so the co-located Dash UI keeps working; client resolves the token per call. No enforcement; /health stays open.
@vercel

vercel Bot commented Sep 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
material-scope Ready Ready Preview Sep 4, 2026 3:22pm UTC

@utkuvibing
utkuvibing merged commit 17ee101 into main Sep 4, 2026
5 checks passed
@utkuvibing
utkuvibing deleted the chore/pr5-security-trio branch September 4, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant