Control-plane authentication, route coverage, and stale-session boundaries¶
A July 30 advisory wave yields one durable control-plane method: verify that authentication policy is attached to every operational route, default deployment state does not create a forgeable authority, low-role capabilities cannot compose into administrator functions, and live sessions lose authority when their backing role changes.
Sources:
- Outstatic GHSA-59rr-38mm-f3g9: an unset
OST_TOKEN_SECRETcan fall back to a source-visible JWT signing default; - Wolf CMS GHSA-xv6g-v6rg-vw4p: a permission-expression precedence flaw can expose backup create, download, and restore functions to non-administrators;
- Wolf CMS GHSA-3pqf-wrr6-rf9m: file-manager users with
file_manager_mkfilecan create PHP-suffixed files in a web-served directory; - Spikster GHSA-rg37-h5w6-fj69:
CipiAuthmiddleware can be registered but unattached to the operational API routes; - Juggle GHSA-8rhq-39vx-cjqx: the stock deployment can expose an H2 console with shipped default credentials and an execution-capable database feature set; and
- MikroTik RouterOS GHSA-x9w7-jgwj-cp2f: active API sessions can retain old permissions after inactivity or user-group changes.
No live credentials or operational actions
Use disposable users, fake signing keys, no-op route handlers, inert file markers, and disconnected lab appliances. Do not publish default credentials, forge production tokens, download real backups, reset passwords, provision servers, create executable files, or issue database command-execution statements.
Recon and preconditions¶
- Identify the exact deployment mode, exposed listener, route prefix, reverse proxy, authentication middleware, session backend, and role model.
- Export or instrument the server route table. Build a matrix for read-only, mutating, backup/restore, file, database-console, account, server-provisioning, and secret-bearing routes.
- Compare intended middleware registration with middleware attached to each route group. A class existing in source or a global-looking declaration is not proof it wraps the effective router.
- Create anonymous, ordinary, feature-limited, administrator, and revoked/downgraded synthetic actors. Seed only marker objects.
- Keep disclosure and mutation tests separate; replace destructive handlers with counters whenever source-instrumented testing is possible.
Default-authority and JWT fallback checks¶
- Start Outstatic with the signing-secret variable absent, empty, malformed, and set to a fresh fake value. Capture startup configuration provenance without printing key material.
- Generate a marker-only token offline using a non-sensitive test key only where the lab confirms a documented/source-visible fallback. Do not reuse or disclose the fallback value.
- Test whether the server accepts caller-selected synthetic identity and role claims, then stop at a harmless
whoamior status route. Do not invoke administrative mutations. - Negative controls: random key, configured unique key, altered algorithm/header, expired marker token, and corrected build.
- Report unset deployment secret -> known fallback selected -> marker token accepted as synthetic authority. Keep secret discovery, token acceptance, and route authorization as separate evidence edges.
Middleware-to-route coverage¶
- Instrument
CipiAuthor equivalent middleware with a no-op counter and actor label. Instrument operational handlers with separate counters that return static marker responses. - Replay one normal request per route as anonymous, malformed-auth, low-role, and administrator actors.
- A route is uncovered only when its handler counter changes while the expected authentication counter does not. Status codes alone can be generated by proxies or error handlers.
- Prioritize password-reset, file read/write, database-user, server provisioning, and configuration route families, but never execute their real side effects.
- Compare direct backend access with the public reverse-proxy path and a corrected router configuration.
Capability composition and web-served file boundaries¶
- In Wolf CMS, establish that a low-role user cannot call backup functions directly through the intended administrator UI. Then test create/list/download/restore authorization independently using synthetic backup names and no-op restore handling.
- For file manager behavior, create only a harmless text marker with a dangerous-looking extension in a disposable web root whose PHP handler is disabled. Record requested filename, persisted suffix, MIME/extension decision, filesystem path, and HTTP handler selection.
- Do not upload PHP code or request interpreter execution. A bounded positive is low-role file-create capability -> dangerous suffix preserved in a web-served location; execution requires a separately proven handler edge.
- Test whether the backup authorization flaw and file-manager capability can actually be held by the same role before describing a chain.
Default console exposure without credential disclosure¶
- Deploy the stock Juggle image in an isolated network and record whether
/h2-consoleis enabled, its bind address, authentication challenge, database URL restrictions, and process identity. - Obtain lab credentials from the authorized test owner or deployment fixture; never extract or publish shipped values.
- After a successful lab login, prove only that an execution-capable H2 feature is present by intercepting the database statement handler or using a no-op alias recorder. Do not invoke
Runtime.exec, shell commands, filesystem reads, or network callbacks. - Repeat with a non-stock deployment, changed credentials, console disabled, and network-restricted console.
- Report the chain as distinct edges: network reachability -> accepted lab/default credential state -> execution-capable database primitive reachable -> recorder fires.
Stale-session authorization matrix¶
- On a disconnected RouterOS lab, create a user with one harmless read permission and establish an API session. Use a second administrator session only to change the test user's group or disable the account.
- Test the already-open session immediately before and after role reduction, inactivity timeout, account disable, password change, explicit logout, and service restart. Use status/version or a synthetic read-only object; do not change network configuration.
- Open a fresh session after each transition as a control. Capture session creation time, backing user/group revision, requested action, authorization decision, and invalidation event.
- A positive is authority reduced in the identity store -> pre-existing session continues a marker operation that a fresh session is denied.
Evidence and reporting¶
Preserve route tables, middleware/handler counter traces, deployment-variable provenance, role/capability matrices, persisted marker metadata, console reachability, and session transition timelines. Name only the proven failure: default authority, middleware coverage gap, permission-expression drift, upload-to-handler precondition, default-console chain, or stale-session permission retention.
October 5 follow-up: auth interceptor scoped to the app prefix leaves the framework console outside it (Northstar)¶
- Northstar (dromara/northstar) ≤ 9.1.1 pre-auth RCE (CVE-2026-88391, GHSA-8hhc-85h8-34q6): the product enables the embedded H2 Console but its authentication interceptor only covers
/northstar/**—/h2-consoleis exposed with no authentication, and the embedded H2 database shipssa/empty-password, so any network-reachable attacker runs arbitrary OS commands viaCREATE ALIAS. Public PoC exists in the advisory references. - This is the Juggle default-console chain on this page completed with its missing edge: the console was reachable not because the product forgot a login page, but because the auth filter's path pattern never included the framework/console route family — same route-family-coverage axis as the June 22 legacy
/jaxrpc/*sweep, inverted (the protection is prefix-scoped, the sink lives outside the prefix). - Replayable checks this adds to the default-console harness above: (1) on any Java/Spring appliance, enumerate console/admin surfaces that live outside the application's own path prefix (
/h2-console,/actuator/*,/druid/*,/swagger-ui/*,/graphql,/jolokia,/management/*) and test each unauthenticated — an interceptor registered on the app prefix proves nothing about these; (2) shipped-default embedded-DB credentials (sa/empty,sa/sa) are a fingerprint, not a publication: prove login acceptance on a disposable instance, prove the execution-capable feature with the page's no-op alias recorder, neverRuntime.exec; (3) report chain edges separately: interceptor-prefix gap → console reachable → default credential accepted → alias recorder fires.