Skip to content

Security: anulum/scpn-fusion-core

SECURITY.md

Security Policy

Supported Versions

Version Supported Notes
3.11.0 Current stable - control/transport/surrogate/equilibrium feature wave (M-4, F-7, M-1, F-5, F-1) with modular-decomposition and validation-evidence passes
3.10.1 Previous stable - CI publication, dependency-maintenance, and release-surface alignment wave
3.10.0 Previous stable - runtime, Studio federation, documentation, and CI/LFS publishing wave
3.9.11 Previous stable - documentation, security-lock, and repository-hygiene wave
3.9.10 Previous stable - documentation, release-evidence, and CI hygiene wave
3.9.9 Previous stable - physics hardening and release-evidence wave
3.9.4 Previous stable - hardening/governance wave
3.9.3 Previous stable — validation-first release line
3.1.0 Superseded (Phase 0 physics hardening)
3.0.0 Superseded (Rust SNN, full-chain UQ, shot replay)
2.0.0 Superseded (multigrid, gyro-Bohm, H-inf controller)
2.1.0 Superseded (GEQDSK, Sauter bootstrap, Spitzer)
1.0.2 Superseded (initial public release)
< 1.0 Pre-release / unreleased

Only the latest 3.x release receives security fixes. Upgrade with:

pip install --upgrade scpn-fusion

Reporting a Vulnerability

If you discover a security vulnerability in SCPN Fusion Core, please report it responsibly:

  1. Email: protoscience@anulum.li
  2. Subject: [SECURITY] SCPN Fusion Core — <brief description>
  3. Do not open a public GitHub issue for security vulnerabilities.

We will acknowledge receipt within 48 hours and aim to provide a fix within 7 days for critical issues.

Scope

SCPN Fusion Core is a simulation library. It does not handle user authentication, financial data, or network services in its default configuration. Security concerns are primarily:

  • Malicious input files (JSON configs, GEQDSK equilibria, NumPy .npz)
  • Unsafe deserialization (serde, pickle, NumPy load)
  • Numerical overflow / denial of service via pathological inputs
  • Native code memory safety (Rust crates via PyO3)
  • Supply chain integrity (dependency audit)

Hardening Measures in Place

Input Validation (v1.0.2 — v3.11.0)

Over 30 hardening commits add runtime guards across all physics and control modules: array shape/dtype checks, non-finite rejection, range clamping, and constructor parameter validation. See the git log for commits prefixed with Harden.

Physics Constraint Enforcement (v3.1.0+)

  • Greenwald density limit rejects unphysical density points in Q-scan
  • Temperature capped at 25 keV with warning emission
  • Q factor capped at 15 to prevent 0-D model artifacts
  • Energy conservation diagnostic in transport solver with optional PhysicsError
  • TBR correction factors enforce realistic [1.0, 1.4] range
  • CI gates: hard fail on FPR > 15%, TBR outside range, Q > 15

Dependency Auditing

  • Rust: cargo audit runs in CI on every push (added in commit a582ef13). Known advisory RUSTSEC-2025-0020 (pyo3 <0.24) was patched by upgrading to pyo3 0.24.
  • Python: Dependencies are minimal (numpy, scipy, matplotlib, streamlit). No pickle.load of untrusted data in any module.
  • Supply-chain automation: hash-pinned requirement locks are used in CI and Docker installs. Dependabot covers GitHub Actions, Python requirements, and Rust Cargo manifests. The security-audit workflow runs pip-audit and cargo-audit, with an optional pinned Snyk audit when SNYK_TOKEN is configured.
  • Checkpoint hygiene: disruption-model checkpoint loading requires torch.load(..., weights_only=True) by default; legacy torch fallback deserialization is disabled unless SCPN_ALLOW_INSECURE_TORCH_LOAD=1 is set for trusted checkpoints.
  • Secure NumPy loading: runtime, validation, and QLKNN training tooling paths use np.load(..., allow_pickle=False) with required-key checks.
  • Parser input hardening: GEQDSK parsing enforces byte, token, grid, contour, finite-value, and shape limits before solver use. IMAS IDS JSON loading enforces byte, nesting-depth, list-length, and equilibrium-grid schema limits before conversion.
  • Fuzzing: Atheris harnesses cover malformed GEQDSK, IMAS IDS JSON, FusionKernel config, and disruption NPZ inputs. Cargo-fuzz covers the Rust domain-decomposition boundary path.
  • Streaming hardening: the phase WebSocket stream binds to loopback by default, refuses exposed bindings unless SCPN_PHASE_STREAM_TOKEN is set, accepts bearer-token or first-message authentication, rate-limits client commands, and supports WSS via explicit certificate/key arguments.
  • Container confinement: the Docker Compose profile runs as a non-root user with all capabilities dropped, no-new-privileges, a read-only root filesystem, bounded tmpfs mounts, seccomp syscall denial, and AppArmor guidance. See docs/security/CONTAINER_HARDENING.md.
  • Bounded subprocesses: CLI mode launches, compiler git-SHA probe, quantum bridge script orchestration, native C++ compile calls, and claims audit git file discovery use explicit subprocess timeouts to avoid indefinite process hangs.
  • Native build hardening: optional C++ compilation is fail-closed behind SCPN_ALLOW_NATIVE_BUILD=1, resolves g++ only from the system default path, rejects symlinked or group/world-writable bundled sources and compiler executables, ignores ambient compiler/linker flags, and executes with fixed argv plus a minimal environment.
  • CI pipeline resilience: Python preflight and strict-mypy tool runners now treat hung subprocesses as deterministic timeout failures.
  • Local command policy: machine-local command-permission settings are excluded from version control.

File-Loader Bounds

  • JSON, G-EQDSK, and NumPy archive production loaders enforce 10 MiB size gates before parsing untrusted files.
  • NumPy archive loaders use allow_pickle=False through a shared bounded loader helper.
  • G-EQDSK parsing rejects unsafe grid and contour counts before array allocation.

Native Library Loading

  • The optional HPC solver bridge refuses existing native libraries unless their SHA-256 digest matches trusted metadata from SCPN_SOLVER_LIB_SHA256, SCPN_SOLVER_TRUST_MANIFEST, or a .sha256 sidecar.
  • Native builds write a SHA-256 sidecar beside the compiled library.
  • Native builds compile only the bundled solver.cpp source through fixed arguments; caller-supplied source files, compiler flags, and inherited build environments are not accepted.

Dashboard Browser Headers

  • The Streamlit dashboard installs response security headers in the Tornado request handler path, including Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, and Referrer-Policy.
  • The dashboard launcher also enables CORS and XSRF protection in the Streamlit runtime configuration.

Fuzzing

  • Atheris-compatible fuzz targets are available for GEQDSK, FusionKernel JSON configuration, and disruption-shot NPZ loading under fuzz/.
  • See docs/security/FUZZING.md for commands and target scope.

RNG Isolation

Global NumPy RNG state is never mutated by library code. All stochastic modules use scoped numpy.random.Generator instances seeded explicitly, preventing cross-module interference. See commits prefixed with Scope and Stop global RNG mutation.

Known Limitations

  • No completed third-party security audit. The codebase has not yet been reviewed by an external security firm. The audit scope and required deliverables are tracked in docs/internal/THIRD_PARTY_AUDIT_SCOPE.md.
  • No CVE history. No vulnerabilities have been reported to date.

Contributions to improve security coverage (fuzzing harnesses, static analysis integration, audit reports) are welcome.

Disclosure Timeline

Date Event
2026-02-12 v1.0.0 initial release
2026-02-12 pyo3 0.23 → 0.24 security upgrade (RUSTSEC-2025-0020)
2026-02-12 cargo audit added to CI
2026-02-13–14 Input hardening sprint (30+ commits)
2026-02-14 v1.0.2 released with full license metadata
2026-02-15 v2.0.0 released — multigrid solver, H-infinity controller
2026-02-16 v2.1.0 released — GEQDSK expansion, Sauter bootstrap
2026-02-17 v3.0.0 released — Rust SNN PyO3, full-chain UQ, shot replay
2026-02-17 v3.1.0 released — Phase 0 physics hardening (Greenwald, TBR, conservation)
2026-02-24 v3.9.2 released — validation-first release line
2026-03-02 v3.9.3 released — hardening/governance wave

There aren't any published security advisories