Skip to content

feat(enrichment): flag deployment-trigger and webhook URLs in secret-scan - #3428

Closed
luciferlive112116 wants to merge 1 commit into
JSONbored:mainfrom
luciferlive112116:feat/enrichment-secret-scan-deploy-hook-urls
Closed

feat(enrichment): flag deployment-trigger and webhook URLs in secret-scan#3428
luciferlive112116 wants to merge 1 commit into
JSONbored:mainfrom
luciferlive112116:feat/enrichment-secret-scan-deploy-hook-urls

Conversation

@luciferlive112116

Copy link
Copy Markdown
Contributor

Summary

Extends the secret-scan analyzer with 7 new high-confidence rules for deployment-trigger and webhook URLs
that embed a secret. These follow the existing URL-credential rules (slack_webhook_url / discord_webhook_url
/ teams_webhook_url / zapier_webhook_url / google_chat_webhook_url): a committed URL of this shape leaks a
capability — anyone who has it can trigger a production deploy or suppress a monitor's alerts.

kind matches leaked capability
netlify_build_hook_url api.netlify.com/build_hooks/<id> triggers a production build
vercel_deploy_hook_url api.vercel.com/v1/integrations/deploy/prj_<id>/<token> triggers a deployment
render_deploy_hook_url api.render.com/deploy/srv-<id>?key=<key> triggers a deployment
healthchecks_ping_url hc-ping.com/<uuid> lets anyone suppress the check's alerts
pipedream_webhook_url <endpoint>.m.pipedream.net invokes the workflow
azure_logic_app_url <host>.logic.azure.com/workflows/…?sig=<sas> triggers the workflow (SAS in sig=)
google_apps_script_url script.google.com/macros/s/<deployment-id>/exec invokes the deployed script

Why these are false-positive-safe. Every match is a full vendor-specific URL (host + the secret
path/param), so an ordinary string can't trip them, and there is no length to guess (the precision class that has
caused past regressions doesn't apply — the host anchors the match). The negative test asserts that vendor
API/docs/dashboard URLs with no secret segment produce nothing, that a Render deploy URL without the key
query param is not flagged, and that a look-alike suffix host (…m.pipedream.net.evil.com) does not match — the
Pipedream rule carries a negative-lookahead terminator to reject exactly that.

All 7 are new kinds (verified against the analyzer's current rule kinds — no duplicate) and inserted before
the generic-assignment rule so the specific kind wins. SecretFinding.kind is a free-form string, so there is
no types.ts/render.ts/analyzer-metadata.json change — a two-file, rules-only diff.

No linked issue: additive detection-coverage extending an existing analyzer along its own established lines; each
rule is a self-evident, industry-standard credential URL with no public API/schema/deploy surface change — fits
the repo's preferred (not required) linked-issue policy.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked an issue, or this is small enough that the summary explains why an issue is not needed.

Validation

  • git diff --check
  • npm run typecheck
  • npm run rees:test — the review-enrichment build + analyzer suite (see note below)
  • npm run test:coverage (N/A — this analyzer is in review-enrichment/, outside the root src/** Codecov scope)
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • Ran locally: git diff --check (clean), the review-enrichment TypeScript build (exit 0), and the secret-scan
    suite via node --test104/104 pass, including a table test asserting each of the 7 new URL formats
    produces exactly one finding of its own kind at high confidence, and a negative test asserting non-secret
    vendor URLs, a param-less Render URL, and a look-alike suffix host produce none.
  • Not run locally: the UI, root typecheck, and the metadata:check step of rees:test. This change adds only
    RULES entries (no analyzer descriptor field), so the committed analyzer-metadata.json / UI mirror are
    unchanged (a local regeneration produces a zero-content diff) and metadata:check passes on CI (Linux). On
    this Windows dev box metadata:check reports a spurious line-ending difference; it fails identically on
    unmodified main. analyzer-metadata.json was NOT modified.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests.
  • API/OpenAPI/MCP behavior is updated and tested where needed.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks.
  • Visible UI changes include a UI Evidence section below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

Notes

  • Detection-only additions: 7 new stateless RULES following the existing specific→generic pattern; no existing
    rule or the analyzer descriptor changed, so current findings and analyzer-metadata.json are unaffected. Each
    new kind reports only file:line + the public-safe kind, never the matched value.
  • Test fixtures are assembled from fragments at run time (never a contiguous secret-shaped literal in source),
    so GitHub push protection does not flag this fixture file.

…scan

Add seven high-confidence RULES for deployment-trigger and webhook URLs that
embed a secret, following the existing URL-credential rules — a committed URL of
this shape leaks a capability (trigger a deploy, suppress a monitor's alerts).

- netlify_build_hook_url: api.netlify.com/build_hooks/<id>
- vercel_deploy_hook_url: api.vercel.com/v1/integrations/deploy/prj_<id>/<token>
- render_deploy_hook_url: api.render.com/deploy/srv-<id>?key=<key>
- healthchecks_ping_url: hc-ping.com/<uuid>
- pipedream_webhook_url: <endpoint>.m.pipedream.net
- azure_logic_app_url: <host>.logic.azure.com/workflows/...?sig=<sas>
- google_apps_script_url: script.google.com/macros/s/<deployment-id>/exec

Each match is a full vendor URL (host + secret path/param), so an ordinary
string cannot trip it and there is no token length to guess. The negative test
asserts non-secret vendor URLs, a param-less Render URL, and a look-alike suffix
host (...m.pipedream.net.evil.com) produce no finding; the Pipedream rule uses a
negative-lookahead terminator to reject that suffix. All kinds are new and
inserted before the generic-assignment rule. SecretFinding.kind is a plain
string, so there is no types/render/metadata change.
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 5, 2026
@loopover-orb

loopover-orb Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Caution

🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥

🛑 Gittensory review result - reject/close recommended

Review updated: 2026-07-05 06:46:53 UTC

2 files · 1 AI reviewer · 1 blocker · readiness 80/100 · CI green · clean

🛑 Suggested Action - Reject/Close

  • AI reviewers agree on a likely critical defect: review-enrichment/src/analyzers/secret-scan.ts:986: `https:​//example.m.pipedream.net-evil.com/path` is a valid look-alike hostname and this rule still reports `pipedream_webhook_url` because `(?![a-z0-9.])` allows `-`
  • change the terminator to reject all hostname continuation characters, e.g. `re: /https:\/\/[a-z0-9]+\.m\.pipedream\.net(?![A-Za-z0-9.-])/`, and add that exact near-miss case. — Resolve the flagged defect, or override if the AI reviewers are mistaken, then re-run the gate.

Review summary
The change cleanly adds vendor-specific secret-scan rules and targeted positive/negative coverage, and the rules are placed before the private-key/generic tail where specific URL kinds can win. I found one reachable false-positive in the Pipedream terminator: the new negative lookahead rejects dotted suffix domains but still accepts valid non-Pipedream hostnames that continue the label with a hyphen.

Blockers

  • review-enrichment/src/analyzers/secret-scan.ts:986: `https:​//example.m.pipedream.net-evil.com/path` is a valid look-alike hostname and this rule still reports `pipedream_webhook_url` because `(?![a-z0-9.])` allows `-`; change the terminator to reject all hostname continuation characters, e.g. `re: /https:\/\/[a-z0-9]+\.m\.pipedream\.net(?![A-Za-z0-9.-])/`, and add that exact near-miss case.
Nits — 4 non-blocking
  • review-enrichment/src/analyzers/secret-scan.ts:979: the Healthchecks UUID rule only accepts lowercase hex, so consider `[A-Fa-f0-9]` or an `i` flag if the service accepts the UUID case-insensitively.
  • review-enrichment/test/secret-scan.test.ts:1599: the Pipedream negative test covers `.evil.com` but not the hyphenated suffix that the comment’s “look-alike suffix domain” rationale should also exclude.
  • Add `https:​//example.m.pipedream.net-evil.com/path` to `nearMisses` in `review-enrichment/test/secret-scan.test.ts` so the host-boundary behavior is locked down.
  • If Healthchecks accepts uppercase UUIDs, extend the positive cases in `review-enrichment/test/secret-scan.test.ts` with one uppercase UUID URL and adjust the regex accordingly.

Why this is blocked

  • review-enrichment/src/analyzers/secret-scan.ts:986: `https:​//example.m.pipedream.net-evil.com/path` is a valid look-alike hostname and this rule still reports `pipedream_webhook_url` because `(?![a-z0-9.])` allows `-`; change the terminator to reject all hostname continuation characters, e.g. `re: /https:\/\/[a-z0-9]+\.m\.pipedream\.net(?![A-Za-z0-9.-])/`, and add that exact near-miss case.
Signal Result Evidence
Code review ❌ 1 blocker 1 reviewer
Linked issue ✅ No-issue rationale PR body explains why no issue is linked.
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (no linked issue context).
Validation posture ❌ 5/25 Preflight is holding this PR: the review lane is unavailable, so it is not ready for automated review.
Contributor workload ✅ 10/10 Author activity: 146 registered-repo PR(s), 80 merged, 21 issue(s).
Contributor context ✅ Confirmed Gittensor contributor luciferlive112116; Gittensor profile; 146 PR(s), 21 issue(s).
Gate result ❌ Blocking Repo-configured hard blocker found.
Review context
  • Author: luciferlive112116
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: not available
  • Official Gittensor activity: 146 PR(s), 21 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Await review-lane availability.
  • Refresh registry data or choose a registered active repo.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 5, 2026
@loopover-orb

loopover-orb Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Gittensory is closing this pull request on the maintainer's behalf (AI reviewers agree on a likely critical defect: review-enrichment/src/analyzers/secret-scan.ts:986: `https:​//example.m.pipedream.net-evil.com/path` is a valid look-alike hostname and this rule still reports `pipedream_webhook_url` because `(?![a-z0-9.])` allows `-`; change the terminator to reject all hostname continuation characters, e.g. `re: /https:\/\/[a-z0-9]+\.m\.pipedream\.net(?![A-Za-z0-9.-])/`, and add that exact near-miss case.). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant