fix(git-clone): accept HTTPS repo URLs on any host, not just GitHub

scanners/lib/git-clone.mjs accepted only github.com, so the README's
Forgejo example (and /security scan on any Forgejo, Codeberg or self-hosted
URL) failed validation; scan.md and plugin-audit.md also routed only
https://github.com/ to the clone path.

Chose generic HTTPS over adding one host to an allowlist because there is
no documented security reason for the host check. Read before choosing:
git log --follow (import + E12 only), the file's comments, CHANGELOG v2.4.0
("GitHub repo URL support", feature framing), security-hardening-guide §2
and §7 (the sandbox is the defence against filter/smudge drivers), and
review-2026-06-20, which lists "vsix-fetch (HTTPS host allowlist)" as a
protection but no host check for git-clone. What protects a clone is the
OS sandbox, GIT_SANDBOX_CONFIG and GIT_SANDBOX_ENV, for every host alike.

Measured: with GIT_SANDBOX_ENV, git reads 0 config lines outside a repo;
without it, osxkeychain comes from Xcode's system gitconfig. So no stored
credential is offered to an unknown host.

The shape stays strict: https only, no userinfo, host starts and ends
alphanumeric (no leading -), optional port, exactly owner/repo, no query
or fragment. SSH stays GitHub-only: ssh uses the user's own keys and
~/.ssh/config, which the git environment does not isolate.

Tests (red first): Forgejo and any-host accept 2 failing -> green; guards
for http, userinfo, leading -, extra path, query, ext:: and file:: and
non-GitHub SSH hold. The old "rejects non-GitHub URL" case still passes
(it has no owner/repo) and is renamed to say so. Regex timed linear
(< 1 ms at 200k chars). Live: a sandboxed clone of
https://git.fromaitochitta.com/open/llm-security.git exits 0 at 5208420,
cleaned up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-22 14:14:39 +02:00
commit 35359b7d8c
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
4 changed files with 48 additions and 11 deletions

View file

@ -7,12 +7,12 @@ model: sonnet
# /security plugin-audit [path|url]
Audit a Claude Code plugin for security before installation. Accepts local paths or GitHub URLs.
Audit a Claude Code plugin for security before installation. Accepts local paths or remote git URLs (HTTPS on any host, SSH on GitHub).
## Step 1: Resolve Target
- If `$ARGUMENTS` contains `--branch <name>` → strip it, set `branch = <name>`
- If `$ARGUMENTS` starts with `https://github.com/` or `git@github.com:` →
- If `$ARGUMENTS` starts with `https://` or `git@github.com:` →
Run: `node <plugin-root>/scanners/lib/git-clone.mjs clone "<url>" [--branch <branch>]`
If exit code != 0 → show error to user and **STOP**
Set `clone_path` = stdout (trimmed), `target = clone_path`

View file

@ -7,14 +7,14 @@ model: sonnet
# /security scan [path|url]
Scan target for security issues. Accepts local paths or GitHub URLs. Delegates to specialized agents sequentially.
Scan target for security issues. Accepts local paths or remote git URLs (HTTPS on any host, SSH on GitHub). Delegates to specialized agents sequentially.
## Step 1: Resolve Target
- If `$ARGUMENTS` contains `--deep` → strip it, set `run_deep_scan = true`
- If `$ARGUMENTS` contains `--branch <name>` → strip it, set `branch = <name>`
- If `$ARGUMENTS` is empty → `target = "."`, `clone_path = null`
- If `$ARGUMENTS` starts with `https://github.com/` or `git@github.com:` →
- If `$ARGUMENTS` starts with `https://` or `git@github.com:` →
Run: `node <plugin-root>/scanners/lib/git-clone.mjs clone "<url>" [--branch <branch>]`
If exit code != 0 → show error to user and **STOP**
Set `clone_path` = stdout (trimmed), `target = clone_path`