Skip to content

release: v3.5.0 — pipeline factory, decorated-route IP/country enforcement, detection ReDoS hardening#40

Merged
rennf93 merged 24 commits into
masterfrom
release/v3.5.0-hardening
Jul 15, 2026
Merged

release: v3.5.0 — pipeline factory, decorated-route IP/country enforcement, detection ReDoS hardening#40
rennf93 merged 24 commits into
masterfrom
release/v3.5.0-hardening

Conversation

@rennf93

@rennf93 rennf93 commented Jul 15, 2026

Copy link
Copy Markdown
Owner

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

  • Global IP whitelist/blacklist and country rules are now enforced on decorated routes; per-route settings override the global gate only for the aspect they actually match, and the IP and country aspects are evaluated independently.
  • A route-level ip_whitelist match 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.
  • Detection ReDoS hardening: linearized built-ins vetted by the safety validator, scan-input caps in every mode, isolated single-worker pattern validation, scan-pool poison recovery, configurable timeout heuristics, and event-loop-safe add_pattern.
  • Redis resilience: socket timeouts, pool cap, health checks, client-level retry, and explicit redis_fail_open (default Falsefail_secure stays authoritative).
  • Non-blocking single-flight cloud-IP refresh routed through the middleware protocol, with a TTL-honoring in-memory store.

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.

rennf93 added 24 commits July 11, 2026 16:11
…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.
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.
@github-actions github-actions Bot added documentation Docs, README, CHANGELOG, governance files area: checks Touches guard_core/core/checks/ area: detection-engine Touches guard_core/detection_engine/ area: handlers Touches guard_core/handlers/ area: decorators Touches guard_core/decorators/ area: core-subsystems Touches guard_core/core/{responses,routing,validation,bypass,behavioral,events,initialization}/ labels Jul 15, 2026
@github-actions github-actions Bot added area: models Touches guard_core/models.py area: sync Touches guard_core/sync/ (sync mirror generated by unasync) area: utils Touches guard_core/utils.py or exceptions.py area: scripts Touches scripts/ tests Test suite changes dependencies pyproject.toml or uv.lock labels Jul 15, 2026
Comment thread tests/test_shared_regex_executor.py Dismissed
Comment thread tests/test_shared_regex_executor.py Dismissed
Comment thread tests/test_sus_patterns/test_add_pattern_contract.py Dismissed
Comment thread tests/test_sus_patterns/test_add_pattern_safety.py Dismissed
Comment thread tests/test_sus_patterns/test_add_pattern_safety.py Dismissed
Comment thread tests/test_sync/test_shared_regex_executor.py Dismissed
Comment thread tests/test_sync/test_sus_patterns/test_add_pattern_contract.py Dismissed
Comment thread tests/test_sync/test_sus_patterns/test_add_pattern_safety.py Dismissed
Comment thread tests/test_sync/test_sus_patterns/test_add_pattern_safety.py Dismissed
Comment thread tests/test_sync/test_sus_patterns/test_add_pattern_safety.py Dismissed
@rennf93
rennf93 merged commit e6de827 into master Jul 15, 2026
10 of 11 checks passed
@rennf93
rennf93 deleted the release/v3.5.0-hardening branch July 15, 2026 04:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: checks Touches guard_core/core/checks/ area: core-subsystems Touches guard_core/core/{responses,routing,validation,bypass,behavioral,events,initialization}/ area: decorators Touches guard_core/decorators/ area: detection-engine Touches guard_core/detection_engine/ area: handlers Touches guard_core/handlers/ area: models Touches guard_core/models.py area: scripts Touches scripts/ area: sync Touches guard_core/sync/ (sync mirror generated by unasync) area: utils Touches guard_core/utils.py or exceptions.py dependencies pyproject.toml or uv.lock documentation Docs, README, CHANGELOG, governance files tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants