{"record":{"id":"0e3d8f8b53449073","repo":"CloakHQ/CloakBrowser","slug":"version-mismatch-in-signed-sha256sums-requested-0e3d8f","errorCode":null,"errorMessage":"Version mismatch in signed SHA256SUMS: requested {requested}, manifest declares {declared or 'none'}. Refusing (possible downgrade).","messagePattern":"Version mismatch in signed SHA256SUMS: requested (.+?), manifest declares (.+?)\\. Refusing \\(possible downgrade\\)\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"cloakbrowser/download.py","lineNumber":673,"sourceCode":"    manifest = _fetch_signed_manifest(version)\n    if manifest is None:\n        raise RuntimeError(\n            \"Could not fetch a signed SHA256SUMS (SHA256SUMS + SHA256SUMS.sig) \"\n            \"for this release — refusing to use an unverified binary. \"\n            \"Retry, or report at https://github.com/CloakHQ/cloakbrowser/issues\"\n        )\n    manifest_bytes, sig_bytes = manifest\n    _verify_signature(manifest_bytes, sig_bytes)\n    manifest_text = manifest_bytes.decode(\"utf-8\")\n\n    # Version binding: the signed manifest must declare the version we asked for.\n    # The signature proves \"we made this manifest\", not \"this is the version you\n    # requested\" — without this check a mirror could serve a genuinely-signed\n    # older release in place of the requested one (forced downgrade).\n    requested = version or get_chromium_version()\n    declared = _parse_manifest_version(manifest_text)\n    if declared != requested:\n        raise RuntimeError(\n            f\"Version mismatch in signed SHA256SUMS: requested {requested}, \"\n            f\"manifest declares {declared or 'none'}. Refusing (possible downgrade).\"\n        )\n\n    checksums = _parse_checksums(manifest_text)\n    expected = checksums.get(tarball_name)\n    if expected is None:\n        raise RuntimeError(\n            f\"Signature-verified SHA256SUMS has no entry for {tarball_name} — \"\n            f\"cannot confirm binary integrity.\"\n        )\n    _verify_checksum(file_path, expected)\n\n\ndef _parse_manifest_version(text: str) -> str | None:\n    \"\"\"Read the 'version=<v>' line from a signed manifest. None if absent.\n\n    The line has no internal whitespace so older wrappers' SHA256SUMS parsers","sourceCodeStart":655,"sourceCodeEnd":691,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/cloakbrowser/download.py#L655-L691","documentation":"The official manifest's signature is valid but the version it declares differs from the requested/default version — the same forced-downgrade defense as the Pro path: a mirror could serve a genuinely-signed older release in place of the requested one.","triggerScenarios":"Official download where _parse_manifest_version(manifest_text) != (version or get_chromium_version()) — stale or mismatched manifest served for the release.","commonSituations":"CDN cache serving an older manifest; proxy pinning old responses; version metadata drift between default-version resolution and the release bucket.","solutions":["Pin the exact version you need and retry with cleared cache","Bypass caching proxies / check DNS","Report upstream with requested vs declared versions"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    install()\nexcept RuntimeError as e:\n    if \"Version mismatch in signed SHA256SUMS\" in str(e):\n        clear_caches(); install()  # bypass stale cache once\n    else:\n        raise","preventionTips":["Pin exact versions and clear caches between pin changes","Watch for caching proxies serving stale signed manifests"],"tags":["security","downgrade","version-mismatch","verification"],"backgroundTag":"version-pin-mismatch","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}