Block direct HTTPS git clone/fetch paths so repos go through git-gate #226

Closed
opened 2026-06-10 02:45:00 -04:00 by didericis-codex · 1 comment
Collaborator

Repro

From this Codex workspace on 2026-06-10, a direct HTTPS clone of the upstream Gitea repo succeeded:

git ls-remote https://gitea.dideric.is/didericis/bot-bottle.git HEAD
# acb9cd67c6bddb1d623fd63ec8274a11f06406f3

git clone https://gitea.dideric.is/didericis/bot-bottle.git bot-bottle-gitea
# exited 0

The existing /home/node/bot-bottle checkout had an origin pointed at a local mirror URL (http://127.0.0.17:59066/bot-bottle.git), but a direct HTTPS clone from gitea.dideric.is was still possible. That bypass is the behavior we want to close.

Expected

Git clone/fetch traffic should not be able to go directly over normal HTTPS egress to forge hosts. Clone/fetch/push for declared repos should be forced through the bot-bottle git-gate/mirror path, where the gate owns upstream credentials and refresh/scanning policy.

Code audit before filing

I checked the current repo for logic that should already enforce this. Relevant findings:

  • Docker compose rendering attaches the agent only to the internal network and sets HTTP_PROXY/HTTPS_PROXY to the egress sidecar (bot_bottle/backend/docker/compose.py).
  • Git-gate writes insteadOf rules only for declared SSH upstream URLs and optional SSH aliases (bot_bottle/git_gate.py). It does not rewrite https://gitea.dideric.is/... URLs.
  • Manifest git upstreams are SSH-only (bot_bottle/manifest_git.py), so HTTPS URLs are outside git-gate's declared upstream matching.
  • The egress addon has an explicit HTTPS Git block, but only for push/receive-pack (is_git_push_request() in bot_bottle/egress_addon_core.py, used by bot_bottle/egress_addon.py). It deliberately returns false for git-upload-pack, which is the clone/fetch path.
  • Unit tests currently lock that in: tests/unit/test_egress_addon_core.py asserts service=git-upload-pack and /git-upload-pack are not considered blocked git push requests.
  • Older docs also reflect the old behavior: docs/prds/0010-cred-proxy.md says receive-pack is blocked but upload-pack/fetch is allowed. That appears to conflict with the desired policy now.

Likely fix direction

Add an egress-side detector for smart HTTP Git upload-pack endpoints (/info/refs?service=git-upload-pack and paths ending /git-upload-pack) and block them for forge hosts that should be served by git-gate, or introduce a more explicit route policy for git-over-HTTP so API access to the same host can remain allowed while clone/fetch cannot. Update tests that currently assert upload-pack is allowed.

## Repro From this Codex workspace on 2026-06-10, a direct HTTPS clone of the upstream Gitea repo succeeded: ```sh git ls-remote https://gitea.dideric.is/didericis/bot-bottle.git HEAD # acb9cd67c6bddb1d623fd63ec8274a11f06406f3 git clone https://gitea.dideric.is/didericis/bot-bottle.git bot-bottle-gitea # exited 0 ``` The existing `/home/node/bot-bottle` checkout had an origin pointed at a local mirror URL (`http://127.0.0.17:59066/bot-bottle.git`), but a direct HTTPS clone from `gitea.dideric.is` was still possible. That bypass is the behavior we want to close. ## Expected Git clone/fetch traffic should not be able to go directly over normal HTTPS egress to forge hosts. Clone/fetch/push for declared repos should be forced through the bot-bottle git-gate/mirror path, where the gate owns upstream credentials and refresh/scanning policy. ## Code audit before filing I checked the current repo for logic that should already enforce this. Relevant findings: - Docker compose rendering attaches the agent only to the internal network and sets `HTTP_PROXY`/`HTTPS_PROXY` to the egress sidecar (`bot_bottle/backend/docker/compose.py`). - Git-gate writes `insteadOf` rules only for declared SSH upstream URLs and optional SSH aliases (`bot_bottle/git_gate.py`). It does not rewrite `https://gitea.dideric.is/...` URLs. - Manifest git upstreams are SSH-only (`bot_bottle/manifest_git.py`), so HTTPS URLs are outside git-gate's declared upstream matching. - The egress addon has an explicit HTTPS Git block, but only for push/receive-pack (`is_git_push_request()` in `bot_bottle/egress_addon_core.py`, used by `bot_bottle/egress_addon.py`). It deliberately returns false for `git-upload-pack`, which is the clone/fetch path. - Unit tests currently lock that in: `tests/unit/test_egress_addon_core.py` asserts `service=git-upload-pack` and `/git-upload-pack` are not considered blocked git push requests. - Older docs also reflect the old behavior: `docs/prds/0010-cred-proxy.md` says receive-pack is blocked but upload-pack/fetch is allowed. That appears to conflict with the desired policy now. ## Likely fix direction Add an egress-side detector for smart HTTP Git upload-pack endpoints (`/info/refs?service=git-upload-pack` and paths ending `/git-upload-pack`) and block them for forge hosts that should be served by git-gate, or introduce a more explicit route policy for git-over-HTTP so API access to the same host can remain allowed while clone/fetch cannot. Update tests that currently assert upload-pack is allowed.
Author
Collaborator

Policy direction from follow-up discussion: keep HTTPS Git access possible, but make it explicit instead of an accidental consequence of host allowlisting. Proposed shape: add a per-egress-route git.fetch: true option. Default behavior should block smart HTTP Git fetch/clone (git-upload-pack) and continue blocking push (git-receive-pack). A route that needs read-only research clones can opt in with git.fetch: true; push should stay blocked for now unless we add a separate, very explicit policy later.

Policy direction from follow-up discussion: keep HTTPS Git access possible, but make it explicit instead of an accidental consequence of host allowlisting. Proposed shape: add a per-egress-route `git.fetch: true` option. Default behavior should block smart HTTP Git fetch/clone (`git-upload-pack`) and continue blocking push (`git-receive-pack`). A route that needs read-only research clones can opt in with `git.fetch: true`; push should stay blocked for now unless we add a separate, very explicit policy later.
didericis added the Kind/Enhancement label 2026-06-10 02:56:53 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: didericis/bot-bottle#226