00.79.40
JS-SEC-024) — the highest-value
item deferred from 00.79.30. No new module. The current release is
00.79.41.Release date: 2026-07-05 Previous release: 00.79.30 Maven coordinates (parent):
com.svenruppert.jsentinel:jSentinel-parent:00.79.40Full changelog: GitHub release v00.79.40
A fresh 12-dimension adversarial source-review — explicitly excluding the 28 findings already closed in 00.79.30 — confirmed 10 distinct findings, all Low: after the previous tick, only defense-in-depth and robustness gaps remained.
Headline — opt-in deny-by-default authorization
JS-SEC-024 (CWE-862) closes the allow-by-omission gap: with
JSentinelServiceResolver.setDenyByDefault(true), an un-annotated @Route or
REST handler is denied (Vaadin error-reroute, REST 403) unless marked
@PublicRoute. A STRICT startup diagnostic enumerates the routes it would
deny, so a forgotten annotation surfaces at boot instead of in production.
Default stays allow-by-omission — fully backward-compatible; existing apps
see no behaviour change unless they opt in. Login / error / public views must
be marked @PublicRoute.
Other findings closed (10, all Low)
- DPoP / JWT / OAuth2 — RSA proof keys under 2048 or over 8192 bits rejected before verification (JS-SEC-029); JWKS
Cache-Control max-ageclamped to 24 h (JS-SEC-033); scope parsing no longer throws on a duplicate/malformed scope string (JS-SEC-034). - Session / authz / audit —
InMemoryAbuseDetectionServiceis now self-reclaiming and hard-bounded, closing a memory-exhaustion path (JS-SEC-030);LoggingAuditSinkand the REST access-context factory scrub CR/LF/control chars, closing a log-injection gapJS-SEC-019didn’t fully cover (JS-SEC-031); a WARN fires when the resolvedSessionPolicyis the inert no-op (JS-SEC-035). - REST / events / propagation / persistence — the security-event SSE stream now self-authorizes before the 200 and any replay (JS-SEC-032); token-propagation HTTP reads are bounded to 1 MiB (JS-SEC-036); the owner-only Eclipse-Store hardening now covers the event feed and the framework storage facade too (JS-SEC-037 / 038).
Two rounds of exit review
Round 1 (three independent reviewers) returned a clean verdict on the
10-finding delta; JS-SEC-024 got its own review and one Medium finding was
fixed in-cycle (the STRICT startup diagnostic now always runs when
deny-by-default is on). Round 2 — a workflow-backed, high-effort pass —
focused specifically on how the new deny-by-default feature interacts with
the framework’s own routes, error navigation and the REST/SSE gates. It
surfaced 10 further findings (RF01–RF10), all fixed in-cycle: an abuse
eviction that could reset a victim’s lockout, deny-by-default correctly
exempting the framework’s own SessionManagementView and Vaadin error views,
a route-registry-unreadable STRICT boot guard, REST deny-by-default returning
401 without a subject, wildcard-aware permission matching for SSE/publish
gates, and a storage-hardening consolidation.
Additivity
The one deliberate signature change is on an @ExperimentalJSentinelApi
type: SseStreamHttpHandler’s constructor now requires a subject resolver
and a required permission (fail-closed, so the event stream can no longer be
wired unauthenticated). Everything else is additive — optional constructor
overloads, one new @PublicRoute marker, and a setDenyByDefault(boolean)
toggle that defaults to off.
Quality
jSentinel-core (the most-touched module) held its 00.79.30 baseline at
84 % (2178/2593). Every finding shipped a new real-implementation
regression test; no test was removed, so coverage cannot regress by
construction. Full reactor clean install green (library modules); standards
pass already-compliant. No mocks.
Migration
None. Deny-by-default stays off unless explicitly enabled. Just bump the
version to 00.79.40.