{"record":{"id":"22c32f6f98ddcd92","repo":"abhigyanpatwari/GitNexus","slug":"unsafe-git-reflog-metadata-blocks-oracle-sanitizat","errorCode":null,"errorMessage":"unsafe Git reflog metadata blocks oracle sanitization","messagePattern":"unsafe Git reflog metadata blocks oracle sanitization","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/oracle_assets.py","lineNumber":408,"sourceCode":"        \"ORIG_HEAD\",\n        \"REBASE_HEAD\",\n        \"REVERT_HEAD\",\n        \"shallow\",\n    ):\n        path = git_dir / pseudo_ref\n        try:\n            metadata = path.lstat()\n        except FileNotFoundError:\n            continue\n        if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISREG(metadata.st_mode):\n            raise ValueError(f\"unsafe Git metadata blocks oracle sanitization: {pseudo_ref}\")\n        path.unlink()\n\n    logs = git_dir / \"logs\"\n    if logs.exists() or logs.is_symlink():\n        logs_metadata = logs.lstat()\n        if stat.S_ISLNK(logs_metadata.st_mode) or not stat.S_ISDIR(logs_metadata.st_mode):\n            raise ValueError(\"unsafe Git reflog metadata blocks oracle sanitization\")\n        shutil.rmtree(logs)\n\n    _git_checked(root, [\"repack\", \"-A\", \"-d\"], timeout=600)\n    _git_checked(root, [\"prune\", \"--expire=now\"], timeout=600)\n    _git_checked(root, [\"prune-packed\"], timeout=600)\n\n    remaining_refs = _git_checked(root, [\"for-each-ref\", \"--format=%(refname)\"], timeout=60)\n    if remaining_refs:\n        raise ValueError(\"oracle sanitization left clone references recoverable\")\n    fsck = run_checked(\n        [\"git\", \"-C\", str(root), \"fsck\", \"--full\", \"--no-progress\", \"--no-reflogs\", \"--unreachable\"],\n        timeout=600,\n        tail_bytes=MAX_CLONE_REF_BYTES,\n    )\n    if fsck.stdout_tail.strip() or fsck.stderr_tail.strip():\n        raise ValueError(\"oracle sanitization left unreachable Git objects recoverable\")\n\n    forbidden_objects: list[tuple[str, str]] = []","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/oracle_assets.py#L390-L426","documentation":"Before `shutil.rmtree(.git/logs)`, the harness verifies .git/logs is a real directory and not a symlink. Calling rmtree on a symlinked logs would follow the link and delete arbitrary tree outside .git, so a symlink (or non-directory) logs is treated as unsafe.","triggerScenarios":"Triggered when .git/logs exists and lstat reports it as a symlink or non-directory (e.g., a regular file, or a symlink pointing outside the repo).","commonSituations":"A crafted clone that symlinks .git/logs to /tmp or another repo; a clone restored from a tarball that did not preserve directory-ness of .git/logs; a filesystem where logs was replaced by a file.","solutions":["Inspect `ls -la <clone>/.git/logs`; if it is a symlink, remove the link: `rm <clone>/.git/logs`.","If it is a regular file, delete it: `rm <clone>/.git/logs` (git will recreate a real directory when needed).","Re-clone from a trusted source if the layout looks crafted."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import stat\nfrom pathlib import Path\n\ndef logs_is_real_dir_or_absent(clone: Path) -> bool:\n    logs = clone / \".git\" / \"logs\"\n    try:\n        st = logs.lstat()\n    except FileNotFoundError:\n        return True\n    return not stat.S_ISLNK(st.st_mode) and stat.S_ISDIR(st.st_mode)\n","typeGuard":"def is_unsafe_reflog_metadata(exc: BaseException) -> bool:\n    return isinstance(exc, ValueError) and \"unsafe Git reflog metadata\" in str(exc)\n","tryCatchPattern":"try:\n    oracle_assets.sanitize_clone_for_hidden_oracles(clone)\nexcept ValueError as exc:\n    quarantine(clone)\n    raise AbortTask(str(exc)) from exc\n","preventionTips":["Never replace .git/logs with a symlink.","Validate clone layout (e.g., via a tarball restore test) before reuse."],"tags":["git","reflog","symlink","rmtree","security","oracle","sanitization","invariant"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}