# Nightfall 0.9.5 — internal security review Review date: 8 September 2026 Assessment: AI-assisted internal source review and targeted regression verification. Not an independent audit, certification, exhaustive penetration test or guarantee. ## Scope and source baseline The Rust baseline is release v0.9.5, commit c773743b627494f892a7bd1bf7cc1f38cb0bb006, protocol 8 / wire 6. 112 Rust source and crate Cargo.toml files matched the local release mirror. The mirror's crates/Cargo.toml/Cargo.lock diff against v0.9.5 was empty. This is an identity check, not evidence that all 112 files were reviewed line by line. Selected paths inspected: consensus emission, checkpoint/replay and reorg rules; ledger aggregation and exploit regressions; storage directory locking; wallet resend/reservation logic; swap availability, persistence and driver states; browser state storage and HTML escaping; Worker proxy, body handling and CSP. Website-only changes described below are not in the release tag. No GitHub changes or push were made. Website publication is Cloudflare-only. ## Method and evidence Command executed on 7 September with Rust 1.98.0, results reviewed 8 September: cargo +1.98.0 test --locked -p nightfall-ledger -p nightfall-consensus -p nightfall-storage -p nightfall-wallet -p nightfall-swap Result: 277 passed, 0 failed, 9 ignored. Selected suites: 8 ledger exploit regressions; 38 chain rules; 21 storage unit tests; 4 foreign-validation-record tests; 3 reorg-persistence tests; 105 swap unit tests; 19 handshake tests; 17 wallet library tests, plus other integration suites. Totals include all selected packages, not the full workspace. Ignored: one ledger timing measurement; one swap regtest; two RPC live tests; one long soak; one happy-path swap live test; three abort-path live tests. No ignored result counts as passed. Earlier regtest runs are project history, not fresh evidence from this review. No production transactions were executed. ## Safeguards with specific regression evidence C-01 Value authorization: exploit_regression.rs tests thin-air mint rejection, unbalanced signable excess, out-of-range output rejection, input authorization, ciphertext tampering, rejected-block state preservation, absence of recipient identifiers and protection against sender reclaim. This supports those cases, not an assertion that unknown inflation or authorization flaws are impossible. C-02 Chain rules: chain_rules.rs exercises fork choice by cumulative work, checkpoint mismatch rejection, validation of untrusted suffixes, emission bounds, timestamp rules and state preservation on rejected blocks. The implementation refuses rewind deeper than 500 blocks. A conflicting history can therefore cause refusal/divergence, not automatic recovery. C-03 Storage: dirlock.rs holds an operating-system advisory writer lock. Tests cover a second holder, release/reacquire and separate directories. Storage tests also exercise migration, binary/JSON format preservation and foreign validation records. The lock does not encrypt seeds, prevent malware, or establish Windows runtime behaviour from this macOS test run. C-04 Liveness: mempool expiry and poisoned-transaction filtering have passing chain-rule regressions. Wallet source retains raw pending sends for retries; Core and browser wiring differ. A retry or accepted submission is not proof of confirmation. The browser outbox has bounded retry retention. C-05 Swaps: the mainnet availability gate is closed and regression-tested. Persistence records intent before broadcast and keeps exact outgoing bytes. Tests reject unknown lock depth as permission to redeem and prevent cancellation after a potentially published redeem. Crash/handshake paths are covered by named unit and integration cases, not by this review's real Bitcoin node execution. ## Open risks and follow-up priorities R-01 HIGH / independent review outstanding. No external audit is established by this assessment. Commission specialist review of the monetary construction, signatures, key derivation, cross-curve proof and protocol composition before treating test coverage as assurance. R-02 HIGH / experimental swap loss, mainnet gated. There is no independent timed NIGHT refund. Alice's recovery can depend on Bob publishing his Bitcoin refund. If Bob never does, NIGHT may stay locked forever; Bitcoin punishment does not unlock it. Late redeem/secret exposure and reorgs remain fundamental hazards. Keep the mainnet gate closed. A new review does not grant approval to open it. R-03 HIGH / browser key exposure, known design limitation. Exported seed-containing wallet state is persisted in localStorage. Website and wallet use the same origin, so path separation is not a storage security boundary. First-party script compromise, malicious extensions or a compromised logged-in device can expose wallet material. CSP and escaping mitigate some injection routes but cannot make compromised first-party deployment safe. Follow-up: separate wallet origin with an explicit migration/recovery plan and evaluate encrypted-at-rest storage. Encryption while locked does not protect an unlocked wallet against active script execution. Neither change is shipped here. R-04 / light-client display and transport trust. The browser uses the same-origin /wallet-api proxy, not full independent chain validation. A node can misrepresent payments, height and confirmations. The current Worker has one configured HTTP upstream. Do not repeat historical two-seed redundancy claims without checking the current configuration. Browser-to-site HTTPS does not encrypt Worker-to-upstream HTTP. The proxy can observe scan requests and transaction submission. Prioritize independent upstream diversity and TLS. This review did not inspect private server logs or establish present hashrate ownership. R-05 / checkpoint and replay trust. Compiled checkpoints and the 500-block rewind bound constrain fork adoption. Checkpoint-anchored replay can skip costly historical validation; the code requires mainnet, an actually reached pin, and checks the pinned hash. NIGHTFALL_NO_ASSUME_VALID disables the checkpoint-based optimization, not every form of trusted local replay. Do not claim every startup independently rechecks every historical proof. Review the chosen checkpoint trust policy and recovery procedures separately from PoW security. R-06 / privacy remains bounded. Block aggregation sorts and merges data but does not apply cut-through. The graph is mixed, not erased. Transaction activity, timing and first-hop observations matter. Tor can fall back to clearnet. No untraceability claim, privacy score or measured deanonymization resistance is established here. R-07 / distribution and local secrets. Checksums compare artifacts; they do not authenticate an attacker-controlled release account or website serving both a binary and its checksum. Trusted publisher signing/notarization is not established. Owner-only file permissions do not encrypt seeds or swap session secrets. Maintain offline recovery backups and protect the local account. A view key reveals financial history even though it cannot spend. ## Website hardening in this revision Worker request handling now bounds incoming bytes during streaming at 512 KiB, including requests without Content-Length, before JSON parsing. JSON shape is checked before method access; malformed objects fail with a controlled response. The method allowlist and all wallet transaction semantics remain unchanged. node scripts/check-website-security.mjs 16 local request cases passed: malformed/primitive JSON, blocked method, HTTP method, oversized ASCII/multibyte/streamed input, permitted status call, CSP separation, wallet no-store and missing-download 404/no-store/no attachment. Upstream calls are mocked; these tests send no real transaction. This is boundary regression testing, not a load test or proof of all DoS bounds. Emission now reports unavailable/stale data, supports refresh and era transitions, and labels node-reported values honestly. check-emission.mjs verifies all 30 table eras with integer dark arithmetic: terminal scheduled issuance 8,999,999,925,000,000 darks = 89,999,999.25 NIGHT. Boundary and invalid-payload checks pass. Dates are projections, not consensus activation dates. ## Not covered No fresh full-workspace run, independent cryptographic proof, dependency/CVE audit, Windows runtime assessment, hardware side-channel assessment, server penetration test, active mainnet attack, operator-key audit or regulatory assessment. Unknown defects can remain even when selected tests pass. ## Reproducible sources https://github.com/Instinctes/nightfall/tree/v0.9.5 https://github.com/Instinctes/nightfall/blob/v0.9.5/crates/nightfall-ledger/tests/exploit_regression.rs https://github.com/Instinctes/nightfall/blob/v0.9.5/crates/nightfall-consensus/tests/chain_rules.rs https://github.com/Instinctes/nightfall/blob/v0.9.5/crates/nightfall-storage/src/dirlock.rs https://github.com/Instinctes/nightfall/blob/v0.9.5/crates/nightfall-swap/src/driver.rs https://github.com/Instinctes/nightfall/blob/v0.9.5/crates/nightfall-swap/src/ui.rs https://github.com/Instinctes/nightfall/blob/v0.9.5/docs/SWAP-LOSS.md ## History and reporting Previous review: /audit/2026-08-16/ (historical, superseded). Current review: /audit/ Private reporting address in the project's policy: security@nightfallcoin.org. Delivery was not tested. Never send seeds, recovery words or RPC credentials.