Token-authenticated subject leaks to anonymous requests on Java 25 (auth bypass) #3168
Pieter Myburgh opened 2 weeks ago

Affected: OneDev 16.8.4. The same code is in 16.7.3. It occurs when running on Java 25+, with Shiro 3.0.1.

Impact: after any request authenticated with an access token (HTTP Basic user:token or Bearer, REST or git over HTTPS), later unauthenticated requests on the same Jetty worker thread run as the token owner. On our instance anonymous internet users were served the admin account. Anonymous access was disabled, and no proxy injected credentials.

Reproduce:

Run OneDev on Java 25 and restart it. Anonymous GET /~api/users/me returns 401 every time. Send a few requests with Authorization: Basic <base64(user:token)> or Bearer . Repeat anonymous GET /~api/users/me. Most calls (25–60 of 60 in our tests) return 200 with the token owner. Run the same steps on Java 21: 0 of 60, even after 40 token calls. Cause:

BasicAuthenticationFilter and BearerAuthenticationFilter call ThreadContext.bind(accessToken.asSubject()) and never unbind. On Java 25+, Shiro's SubjectCallable uses ScopedValues and no longer creates a SubjectThreadState, so ThreadContext is never restored after the request. io.onedev.server.security.SecurityUtils.getSubject() checks ThreadContext.getSubject() before the scoped value. The stale subject on the pooled thread therefore wins, and the auth filters skip it because isAuthenticated() is true. Suggested fix: in ExceptionHandleFilter.cleanup:

try { super.cleanup(request, response, existing); } finally { // Shiro uses ScopedValues on Java 25+ and no longer restores ThreadContext ThreadContext.unbindSubject(); } Other ThreadContext.bind call sites may need the same audit.

Workaround: run OneDev on Java 21, e.g. wrapper.java.command in conf/wrapper.conf.

  • Robin Shen changed title 2 weeks ago
    Previous Value Current Value
    Security: token-authenticated subject leaks to anonymous requests on Java 25 (auth bypass)
    Token-authenticated subject leaks to anonymous requests on Java 25 (auth bypass)
  • OneDev commented 2 weeks ago

    State changed as build OD-8640 (16.8.5) is successful

  • OneDev changed state to 'Closed' 2 weeks ago
    Previous Value Current Value
    Open
    Closed
  • Robin Shen changed confidential 2 weeks ago
    Previous Value Current Value
    true
    false
1/1
Type
Security Vulnerability
Priority
Critical
Assignee
Affected Versions
16.7.3 -> 16.8.4
Labels
No labels
Issue Votes (0)
Watchers (3)
Reference
OD-3168
Please wait...
Connection lost or session expired, reload to recover
Page is in error, reload to recover