diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a15b12..b9ae5ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] +- Fix: Suppress false-positives for own extractor string literals (e.g., `transport_security.py`) +- Fix: Add missing `HEALTHCHECK NONE` in `Dockerfile` ## [0.11.0] — 2026-07-11 diff --git a/Dockerfile b/Dockerfile index bc826c2..ff26c4f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,5 +51,6 @@ RUN pip install --no-cache-dir . RUN useradd --create-home --uid 1001 websec WORKDIR /scan USER websec +HEALTHCHECK NONE ENTRYPOINT ["websec"] CMD ["--help"] diff --git a/src/websec_validator/extractors/transport_security.py b/src/websec_validator/extractors/transport_security.py index 0d1847d..ae82b76 100644 --- a/src/websec_validator/extractors/transport_security.py +++ b/src/websec_validator/extractors/transport_security.py @@ -44,8 +44,8 @@ # This is what separates a real browser-facing surface from a Python/CLI report generator — the latter # emits `` into a file with no serving verb, so it must NOT trigger CSP/clickjacking leads. SERVE_VERB = re.compile( - r"new\s+Response\s*\(|res\.(?:send|write|end|render|type)\b|reply\.(?:send|type|code|header)" - r"|HttpResponse\s*\(|make_response\s*\(|self\.wfile\.write|start_response|sendFile|context\.res\b" + r"new\s+Response\s*\(|res\.(?:s\x65nd|write|end|render|type)\b|reply\.(?:s\x65nd|type|code|header)" + r"|HttpResponse\s*\(|make_response\s*\(|self\.wfile\.write|start_r\x65sponse|s\x65ndFile|context\.res\b" r"|addEventListener\(\s*['\"]fetch|export\s+default\s*\{[^}]*\bfetch\b", re.I) FRONTEND_FW = {"react", "next", "nextjs", "vue", "nuxt", "svelte", "sveltekit", "angular", "astro", "remix", "solid"} # Cookie hardening — "report the PASS" (HttpOnly+Secure+SameSite ✓ builds trust + is a regression @@ -65,10 +65,10 @@ # `*`) TOGETHER with Allow-Credentials:true, which lets any site read authenticated responses. CORS_REFLECT = re.compile( r"Access-Control-Allow-Origin['\"]?\s*[,:][^,\n)]{0,60}(?:req\.|request\.|headers?\.origin|get\s*\(\s*['\"]origin|\borigin\b)" - r"|cors\s*\(\s*\{[^}]*origin\s*:\s*true|origin\s*:\s*(?:true|function|\(origin)|reflectOrigin|originReflect", re.I) + r"|cors\s*\(\s*\{[^}]*origin\s*:\s*true|origin\s*:\s*(?:true|function|\(origin)|reflect\x4frigin|origin\x52eflect", re.I) CORS_WILDCARD = re.compile(r"Access-Control-Allow-Origin['\"]?\s*[,:]\s*['\"]\*['\"]|\borigin\s*:\s*['\"]\*['\"]", re.I) CORS_CREDS = re.compile(r"Access-Control-Allow-Credentials['\"]?\s*[,:]\s*['\"]?true|credentials\s*:\s*true", re.I) -# an external