fix(scanner): narrow CORS wildcard regex + skip doc files + negation filter - #484
Merged
Merged
Conversation
…filter (#483) The static security scanner's CORS rule used an overly broad regex that matched any occurrence of the word 'cors' followed by '*' anywhere on the line. This triggered false positives on: - Env var names like TITEN_CORS_ORIGINS (contains 'cors' + '*' from markdown bold) - Documentation prose mentioning CORS configuration - Comments instructing developers NOT to use wildcards Three-layer fix: 1. Narrow regex to require actual code patterns: - Access-Control-Allow-Origin: * (HTTP header) - cors = * / allow_origin(*) / origin: * / allowed_origins = * - Method calls like .allow_origin(*) now matched via [=:(] delimiter 2. Skip non-code files (.md, .txt, .rst, .adoc, .tex, .org, etc.) Security patterns are designed for source code, not prose. 3. Post-match negation context filter: Suppresses matches in negation contexts like 'no wildcard', 'do not use *', 'without wildcard', and env var name patterns (cors_origins, cors_allowed, cors_config). Tests: 25 new test cases covering true positives, false positives from issue #483, doc file detection, and negation context suppression.
This was referenced Aug 4, 2026
Closed
ajianaz
added a commit
that referenced
this pull request
Aug 4, 2026
…ation filter edge cases (#488, #489) PR #484 narrowed the CORS regex to fix false positives (#483), but the narrowing was too aggressive: 13 of 14 common framework-specific CORS wildcard patterns were no longer detected. Changes: 1. Rewrite CORS regex with 10 framework pattern alternatives using (?ix) extended mode: HTTP header, generic assignment, Django, Spring Boot, .NET, tower-http, Express, FastAPI, nginx, actix-web. 2. Remove unsupported lookahead (?!\w) — Rust regex crate limitation. Use explicit trailing delimiters instead. 3. Fix negation filter: skip suppression when comment body contains code indicators (=, fn, let, const) after negation phrase. 4. Fix cors_config suppression: only suppress env::var() read patterns, not bare CORS_CONFIG = "*" assignments (real finding). 5. Pre-compile negation regexes with LazyLock for performance. 6. Fix is_doc_file(): check for dot before extracting extension. Prevents extensionless files ('org', 'tex', 'md') being treated as docs. Tests: 836 pass, 0 fail, 0 clippy warnings, fmt clean. Closes #488, closes #489.
10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes the CORS wildcard security scanner rule that produced false positives on documentation, env var names, and negation contexts (e.g., "do not use *").
Why
The original regex
(?i)(?:Access-Control-Allow-Origin|cors).*\*matched any line containing the word "cors" followed by*anywhere after it. This triggered false positives on:TITEN_CORS_ORIGINS— contains "cors", then*from markdown bold**or URL patternsThis caused stale/incorrect check-run failures on PRs in downstream repos using
cora-review-action(e.g., titen#38, titen#39), requiring--adminmerge override.Closes #483
How
Three-layer defense-in-depth fix:
1. Narrow regex (security_scanner.rs)
Before:
(?i)(?:Access-Control-Allow-Origin|cors).*\*— matches "cors" + any*After: Requires actual code assignment/call syntax:
Access-Control-Allow-Origin: *— literal HTTP headercors = "*",allow_origin("*"),allowed_origins = "*"— code patterns with[=:(]delimiterorigin: *,origin = "*"— config/key patternsThe standalone word "cors" no longer triggers — it must be part of a code pattern.
2. Skip non-code files (security_scanner.rs)
Added
is_doc_file()check — security scanner now skips.md,.markdown,.mdx,.txt,.rst,.adoc,.asciidoc,.tex,.orgfiles entirely. Security patterns are designed for source code, not prose.3. Post-match negation filter (builtin.rs)
Added
is_false_positive_cors()topost_match_filter()— suppresses matches when the line contains negation context:cors_origins,cors_allowed,cors_configTesting
cargo testpasses — 821 tests (799 unit + 16 CLI + 6 integration), 0 failurescargo fmt --all -- --checkpassescargo clippy --all-targets -- -D warningspassesTest coverage added (25 new tests):
security_scanner.rs (14 tests):
detects_cors_wildcard_header— real HTTP header still detecteddetects_cors_wildcard_assignment—cors_origin = "*"detecteddetects_allowed_origins_wildcard—allowed_origins = "*"detectedno_false_positive_cors_env_var_name—TITEN_CORS_ORIGINSdoes not triggerno_false_positive_cors_in_prose— comment text does not triggerno_false_positive_markdown_file—.mdfiles skipped entirelyno_false_positive_txt_file—.txtfiles skippedno_false_positive_rst_file—.rstfiles skippedreal_cors_wildcard_in_rust_still_detected—.allow_origin("*")still triggersis_doc_file_recognizes_common_extensions— 9 doc extensions detectedis_doc_file_does_not_match_code_files— 8 code extensions/files pass throughbuiltin.rs (6 tests):
cors_negation_no_wildcard_is_false_positivecors_negation_no_catch_all_is_false_positivecors_negation_do_not_use_wildcard_is_false_positivecors_env_var_name_is_false_positivecors_actual_wildcard_is_not_false_positive— ensures real wildcards NOT suppressedcors_unrelated_rule_not_affected— filter only applies to cors ruleRelated Issues
Closes #483
Checklist
fix/cors-scanner-false-positive-483)develop