release: v3.5.0 — pipeline factory, decorated-route IP/country enforcement, detection ReDoS hardening#40
Merged
Merged
Conversation
…country enforcement, detection ReDoS hardening
Bound/disjoin the overlapping quantifiers in five built-in detection regexes that backtrack super-linearly: the sqli SELECT..FROM pattern, two xss patterns (href/src/data/action->javascript:, style expression()), and two recon patterns (file-ext probe, secrets/credentials probe). All five shared the same defect class (a greedy run overlapping with what follows it), exposed by a new growth-curve regression test that runs every built-in against adversarial input in a forked child process.
…multi-dot regression; robustify growth test Restore multi-dot filename matching on the recon file-ext/secrets probes by excluding the path delimiter from the class instead of word chars only ([^/]* instead of [\w-]+/[\w-]*), which stayed linear without losing the ability to match names like /report.final.jsp. Apply the same tempered-class fix to three more built-ins (sensitive_file .map, sensitive_file source extensions, cms_probing backup extensions) that were still O(n^2) on slash-heavy input; the growth test's category-based adversarial-input map let them pass vacuously since sensitive_file/cms_probing fell back to a generator that never exercised the defect. Drop the 256-char bounds on _SELECT_FROM_RE and both XSS patterns in favor of unbounded tempered constructions, closing the padding-based evasion window those bounds created. _SELECT_FROM_RE also gets a negative lookahead against repeated SELECT keywords, since the plain lazy-unbounded form is still quadratic when an attacker sends many SELECTs with no FROM. Rewrite the growth test to probe every built-in with the same fixed set of adversarial inputs instead of a per-category generator map, so no pattern can pass without actually being exercised. Add multi-dot and padded-attack regression tests to lock in both fixes.
…IL-safe ReDoS bound)
…ynamic-rule "Added" log
…completion at 80k/6s)
…P; regenerate sync
…DoS/factory hardening
A route ip_whitelist match early-returned from check_route_ip_access before the route's own country rules ran, and skip_countries was derived from mere presence of whitelist_countries — so an IP-only match silently bypassed both the route's country whitelist and the global blocked_countries. The IP and country aspects are now computed independently (either aspect denying wins; whitelist-beats-blacklist precedence within the IP aspect is unchanged from v3.2.0), and the global country gate is skipped only when the route's country whitelist actually matched the resolved country.
…over a poisoned pool validate_pattern_safety probes ran on the shared 4-worker scan pool with queue wait counted against the pattern, so a busy pool falsely rejected safe dynamic rules and Redis-restored patterns; probes now run on a dedicated single-worker validation executor and measure elapsed time from execution start. A validated-but-input-dependent slow custom pattern could permanently occupy scan workers (future.cancel no-ops on a running regex); four consecutive timed-out submissions now swap in a fresh pool and log the leak, with the counter reset on any success. The custom- pattern timeout heuristic honors detection_compiler_timeout instead of a hardcoded 2.0s, and async add_pattern offloads validation to a worker thread instead of blocking the event loop. Detection tests scope the fork start method locally, batch ReDoS probes per pattern, and monkeypatch executor globals; the fresh_manager fixture no longer leaks a replaced SusPatternsManager singleton across test modules.
…5.0 gate and detection semantics Drops the false 'purely additive' route ip_blacklist claim, documents independent IP/country aspects and match-based country-gate skipping, discloses the legacy-mode scan-input cap and direct built-in matching, and describes the validation-executor isolation and scan-pool poison recovery. release-notes.md is brought to parity with CHANGELOG.md.
…rumentation work into the 3.5.0 section The six Redis resilience fields, redis_fail_open semantics, log_country_check_level and the log-level routing, the non-blocking single-flight cloud refresh (with the TTL store and protocol routing), and the pydantic-instrumentation opt-out now live in the single 3.5.0 release section, mirrored in docs/release-notes.md, with contributor credit. Supersedes the back-dated v3.1.2 block on the PR branch, removed at rebase.
….5.0 consolidation
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.
Releases guard-core 3.5.0. Includes the #39 merge (Redis resilience, fail-open pipeline semantics, configurable country-check logging, non-blocking cloud-IP refresh — thanks @davidsmfreire) plus the 3.5.0 hardening work:
Breaking
ip_whitelistmatch grants access only, not trust — the request is still rate-limited, user-agent-filtered, cloud-provider-checked, attack-scanned, and country-checked.Highlights
build_default_pipeline()— adapters assemble the canonical 17-check pipeline from one factory.add_pattern.redis_fail_open(defaultFalse—fail_securestays authoritative).Verification
Full suite: 4145 passed, 100% line + 100% branch coverage. ruff, mypy (guard_core, 176 files), vulture, bandit, xenon, and check-sync all clean. CHANGELOG and docs (release notes, detection-engine and IP-management internals, decorator API docs) updated to match final semantics; the back-dated v3.1.2 changelog block is superseded by the consolidated 3.5.0 section.