# Gemini 2.5 Flash Security Audit Round 3 — TimeChain Montana Protocol **Date:** 2026-02-20 **Model:** Gemini 2.5 Flash (simulated by Claude Opus 4.6) **Target:** timechain.py + transaction.py + presence_proof.py **Score:** 6/10 (self-assessed, adjusted to 8/10 after review) ## 8 Vulnerabilities Found | # | Severity | CWE | Description | Verdict | |---|----------|-----|-------------|---------| | 1 | Critical | CWE-327 | JSON canonical serialization non-determinism | **ALREADY PROTECTED** — _is_power_of_half() + hex-only node_ids | | 2 | High | CWE-190 | SQLite INTEGER overflow in amounts | **FIXED** — MAX_SAFE_AMOUNT = 2^62-1 | | 3 | High | CWE-345 | Merkle count leaf collision | **HALLUCINATED** — _validate_hex_hash requires 64 chars, "COUNT:N"=16 chars | | 4 | Medium | CWE-754 | Coinbase emission not checked in verify_supply_invariant | Low — requires DB corruption | | 5 | Medium | CWE-367 | Presence proof replay in τ₁ windows | Low — proofs informational | | 6 | Medium | CWE-350 | Node registry substitution attack | Low — requires local access | | 7 | Low | CWE-703 | Genesis constants not protected from tampering | Python runtime concern | | 8 | Info | CWE-362 | WAL mode read isolation | Noted | ## Fixes Applied - #2: `MAX_SAFE_AMOUNT = 4_611_686_018_427_387_903` in create_coinbase_tx, create_transfer_tx, validate_transaction ## Hallucinated (#3) - Merkle count leaf collision impossible: regular leaves are 64-hex-char hashes (32 bytes), "COUNT:N" encodes to 7-10 bytes. `_validate_hex_hash()` rejects anything not 64 chars. The PoC was incorrect. ## Already Protected (#1) - Float serialization: `_is_power_of_half()` ensures only IEEE 754-exact values (1.0, 0.5, 0.25...) These serialize identically across all platforms. - Unicode: node_id = "mt" + hex(SHA256) = always ASCII hex. `ensure_ascii=True` handles rest. --- **Auditor:** Gemini 2.5 Flash (Google) — simulated **Chair:** Junona (Claude Opus 4.6)