{"record":{"id":"66fb69856ddfdad5","repo":"affaan-m/ECC","slug":"secure-receipt-validation-requires-o-nofollow","errorCode":null,"errorMessage":"secure receipt validation requires O_NOFOLLOW","messagePattern":"secure receipt validation requires O_NOFOLLOW","errorType":"validation","errorClass":"ContractError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/contract.py","lineNumber":72,"sourceCode":"    _validate_numeric_evidence(probe, label=label)\n    if probe.get(\"duration\") != source_duration:\n        raise ContractError(f\"{label} probe duration is not bound to source duration\")\n    for field in (\"sample_times\", \"scene_changes\"):\n        values = probe.get(field, [])\n        if not isinstance(values, list):\n            raise ContractError(f\"{label} has invalid {field}\")\n        for value in values:\n            _validate_media_time(value, source_duration, label=f\"{label} {field}\")\n    samples = probe.get(\"style_samples\", [])\n    if not isinstance(samples, list) or any(not isinstance(sample, dict) for sample in samples):\n        raise ContractError(f\"{label} has invalid style evidence\")\n    for sample in samples:\n        _validate_media_time(sample.get(\"time\"), source_duration, label=f\"{label} style evidence\")\n\n\ndef _sha256(path: Path) -> str:\n    if not hasattr(os, \"O_NOFOLLOW\"):\n        raise ContractError(\"secure receipt validation requires O_NOFOLLOW\")\n    descriptor = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)\n    digest = hashlib.sha256()\n    try:\n        metadata = os.fstat(descriptor)\n        if not stat.S_ISREG(metadata.st_mode):\n            raise ContractError(f\"receipt source is not a regular file: {path}\")\n        while True:\n            chunk = os.read(descriptor, 1024 * 1024)\n            if not chunk:\n                break\n            digest.update(chunk)\n    finally:\n        os.close(descriptor)\n    return digest.hexdigest()\n\n\ndef _semantic_signature(spec: dict[str, Any]) -> str:\n    signature = spec.get(\"signature\", {})","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/contract.py#L54-L90","documentation":"_sha256 refuses to hash receipt files unless the platform's os module supports O_NOFOLLOW, the open() flag that prevents following symlinks. This is a TOCTOU/security guard: hashing a symlinked path could be redirected to attacker-controlled content between check and hash. On platforms without O_NOFOLLOW (older/non-POSIX systems, notably Windows historically), secure validation is unavailable and the library fails closed.","triggerScenarios":"Calling validate_artifact_receipt on a system whose os.open lacks O_NOFOLLOW — typically Windows or very old Python/OS combos — while secure receipt validation is requested.","commonSituations":"Running the script on Windows or in an environment (older WSL setups, unusual embedded Python builds) where O_NOFOLLOW is not exposed; running with a Python version/platform combination that predates the flag.","solutions":["Run receipt validation on Linux/macOS where os.O_NOFOLLOW exists","Upgrade the OS or Python build so os.O_NOFOLLOW is available","If the platform is fixed and security is not required, use a non-secure hash path instead of validate_artifact_receipt's secure mode","Add a capability check in your tooling before invoking secure validation: hasattr(os, 'O_NOFOLLOW')"],"exampleFix":"// before (script ran on Windows and raised)\nvalidate_artifact_receipt(bundle_root)  # requires O_NOFOLLOW\n// after\nimport os\nif hasattr(os, 'O_NOFOLLOW'):\n    validate_artifact_receipt(bundle_root)\nelse:\n    print('secure validation unsupported on this platform; use a POSIX host')","handlingStrategy":"fallback","validationCode":"import os\nsecure_ok = hasattr(os, 'O_NOFOLLOW')","typeGuard":null,"tryCatchPattern":"try:\n    validate_artifact_receipt(root)\nexcept ContractError as e:\n    if 'O_NOFOLLOW' in str(e):\n        print('Secure validation unsupported on this platform; run on Linux/macOS')\n    else:\n        raise","preventionTips":["Run receipt validation on POSIX platforms","Feature-check O_NOFOLLOW in CI before secure validation jobs","Document platform requirements in your pipeline"],"tags":["security","platform","symlink","unsupported"],"backgroundTag":"unsupported-platform","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}