From 45aed0843dd6546a4000bf8caf6bbcfc4350b97c Mon Sep 17 00:00:00 2001 From: jeffrey701 Date: Sun, 5 Jul 2026 13:57:39 -0400 Subject: [PATCH] feat(enrichment): allowlist 0.0.0.0 in the hardcoded-URL analyzer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ALLOWLISTED_HOSTS treated localhost/127.0.0.1/example.com as placeholders but not 0.0.0.0, the unspecified/localhost bind address — so `http://0.0.0.0:PORT` (a dev/bind placeholder, not a real endpoint) was flagged as a hardcoded URL. Adds it + extends the allowlist test. --- .../src/analyzers/hardcoded-url.ts | 291 +++++++++--------- review-enrichment/test/hardcoded-url.test.ts | 178 +++++------ 2 files changed, 238 insertions(+), 231 deletions(-) diff --git a/review-enrichment/src/analyzers/hardcoded-url.ts b/review-enrichment/src/analyzers/hardcoded-url.ts index c5790d50ba..a4ea3d1d07 100644 --- a/review-enrichment/src/analyzers/hardcoded-url.ts +++ b/review-enrichment/src/analyzers/hardcoded-url.ts @@ -1,143 +1,148 @@ -// Hardcoded-URL / raw-endpoint analyzer (#2027). Flags absolute HTTP(S) URLs and IP:port endpoints newly -// added in non-test, non-config source — often environment leakage or a value that should come from config. -// Distinct from the secret scanner (no credential); this is a portability/config-hygiene signal. Pure compute -// over added lines, no network. Hostnames are redacted/truncated in findings — never full paths or queries. -import type { EnrichRequest, HardcodedUrlFinding } from "../types.js"; -import { isMagicNumberSourcePath } from "./magic-number.js"; - -const MAX_FINDINGS = 25; -const MAX_LINE_CHARS = 2000; -const MAX_HOST_CHARS = 40; - -const CONFIG_PATH_RE = - /(?:^|\/)(?:docker-compose[^/]*\.ya?ml|compose[^/]*\.ya?ml|values(?:\.[^/]+)?\.ya?ml|\.env(?:\.[^/]+)?|.*\.(?:tf|tfvars|hcl|ya?ml|json|toml|ini|conf|env)|Dockerfile(?:\.[^/]+)?|nginx[^/]*\.conf)$/i; - -const HTTP_URL_RE = /https?:\/\/[^\s'"\`<>]+/gi; -const IP_ENDPOINT_RE = /\b(?:\d{1,3}\.){3}\d{1,3}:\d{1,5}\b/g; - -const ALLOWLISTED_HOSTS = new Set(["localhost", "127.0.0.1", "example.com"]); - -function isConfigPath(path: string): boolean { - return CONFIG_PATH_RE.test(path); -} - -function isScannablePath(path: string): boolean { - return isMagicNumberSourcePath(path) && !isConfigPath(path); -} - -function redactHost(host: string): string { - const lower = host.toLowerCase(); - if (lower.length <= MAX_HOST_CHARS) return lower; - return `${lower.slice(0, MAX_HOST_CHARS - 3)}...`; -} - -function isAllowlistedHost(host: string): boolean { - const lower = host.toLowerCase(); - if (ALLOWLISTED_HOSTS.has(lower)) return true; - if (lower.endsWith(".example.com")) return true; - return false; -} - -function hostFromHttpUrl(url: string): string { - const match = /^https?:\/\/([^/?#:]+)(?::\d+)?/i.exec(url); - return match?.[1] ?? url; -} - -function isCommentLine(line: string): boolean { - const trimmed = line.trimStart(); - return /^(?:\/\/|#|\/\*|\*|