mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-12 07:59:02 +02:00
fix: don't flag git SSH remotes as pii.email
`pii.email` matches the `git@github.com` inside `git@github.com:acme/widgets.git`. That is a transport user@host, not a person's address, so any diff touching a clone URL -- a deploy config's repo URL, a submodule entry, a README clone line -- draws a spurious MEDIUM from the pre-push hook. Suppressed by URL shape rather than by adding `git` to EMAIL_ALLOW_LOCALPARTS. A bare `git@` allowlist entry would also suppress a genuine address at a domain that merely begins with "git" (git@gitmail.com), converting a false positive into a false negative -- the worse failure for a guardrail. Two shapes are accepted: - `<user>@<host>:<path>.git` for ANY host, covering self-hosted remotes, plus the equivalent ssh:// URL form. - `git@<known-host>` for github.com, gitlab.com, bitbucket.org and ssh.dev.azure.com, whose bare form appears in docs and in `ssh -T git@github.com` connectivity checks with no path at all. Matched exactly, so gitmail.com is unaffected. emailAllowed now receives the normalized text and the span offset so it can see that surrounding shape; it had only ever been passed the matched span. Tests pin both directions: the SSH remotes go quiet, and a real address still fires -- including at a git host (alex@github.com) and at a git-prefixed domain (git@gitmail.com). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Garry Tan
co-authored by
Claude Opus 5
parent
cc94bc34ba
commit
0340862e01
@@ -312,6 +312,28 @@ describe("PII patterns", () => {
|
||||
scan("bob@acme.co", { repoVisibility: "private", repoPublicEmails: ["bob@acme.co"] }).findings,
|
||||
).toHaveLength(0);
|
||||
});
|
||||
// A git SSH remote's `git@host` is a transport user@host, not a person's
|
||||
// address. Suppressed by URL SHAPE rather than by allowlisting the `git`
|
||||
// local part: a bare `git@` entry would also silently hide a real address
|
||||
// at a domain that merely starts with "git".
|
||||
test("ssh git remotes are not flagged as emails", () => {
|
||||
expect(ids("set :repo_url, 'git@github.com:acme/widgets.git'")).not.toContain(
|
||||
"pii.email",
|
||||
);
|
||||
expect(ids("git clone git@gitlab.com:acme/widgets.git")).not.toContain("pii.email");
|
||||
expect(ids("git@bitbucket.org:acme/widgets.git")).not.toContain("pii.email");
|
||||
expect(ids("git@ssh.dev.azure.com:v3/acme/widgets/widgets")).not.toContain("pii.email");
|
||||
expect(ids("ssh -T git@github.com")).not.toContain("pii.email");
|
||||
// General case: any host in <user>@<host>:<path>.git position.
|
||||
expect(ids("git@git.acme-internal.net:infra/tools.git")).not.toContain("pii.email");
|
||||
expect(ids("ssh://git@scm.acme-internal.net/infra/tools.git")).not.toContain("pii.email");
|
||||
});
|
||||
test("a real address is still flagged, including at a git host", () => {
|
||||
expect(ids("ping alex@github.com about the issue")).toContain("pii.email");
|
||||
// A domain that merely STARTS WITH "git" is not a git host — this is the
|
||||
// case a bare `git@` local-part allowlist would have wrongly suppressed.
|
||||
expect(ids("contact git@gitmail.com for access")).toContain("pii.email");
|
||||
});
|
||||
test("phone E.164 flags, skips compact timestamps", () => {
|
||||
expect(ids("call +14155550123 now")).toContain("pii.phone.e164");
|
||||
expect(ids("backup stamp 20260727202423 ran late")).not.toContain("pii.phone.e164");
|
||||
|
||||
Reference in New Issue
Block a user