[ 
https://issues.apache.org/jira/browse/RANGER-5693?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ramachandran Krishnan updated RANGER-5693:
------------------------------------------
    Description: 
h2. Summary

Apache Ranger's JWT authentication handler ({{{}RangerJwtAuthHandler{}}}) logs 
the full
serialized JWT bearer token (header.payload.signature) at WARN level when token
validation fails. For some failure modes—especially audience mismatch after a
valid signature and unexpired token—the logged credential remains live and can 
be
replayed against another Ranger JWT endpoint that trusts the same signing 
material
and accepts the token's audience.
h2. Affected component
 * Module: {{ranger-authn}}
 * Class: {{org.apache.ranger.authz.handler.jwt.RangerJwtAuthHandler}}
 * Method: {{authenticate(String jwtAuthHeader)}} — validation-failure WARN path
 * Also used via: {{RangerDefaultJwtAuthHandler}} (Admin, PDP, audit paths, 
etc.)

h2. Affected versions

Verified on Apache Ranger 2.8.0. Same pattern present on ranger-2.8, ranger-2.9,
and master at time of report.
h2. Problem

On validation failure, the handler logs:
{{jwtToken.serialize()}}
which writes the complete bearer credential to operational logs.

{{validateToken()}} checks claims in order: expiration → signature → audience → 
issuer.
A cryptographically valid, unexpired token rejected only for audience mismatch 
still
hits the WARN branch and is logged in full.
h2. Impact

An actor with read access to Ranger operational logs (operators, log 
aggregation,
log storage) can recover a live JWT from a WARN entry and replay it against 
another
Ranger JWT consumer configured for that token's audience, authenticating as the
token subject.

This is not limited to malformed or unsigned tokens; reporter verified with a 
valid
RS256-signed JWT and future expiration.
h2. Root cause

{{RangerJwtAuthHandler.authenticate()}} logs the raw serialized token when
{{validateToken()}} returns false (historically around line 128 on master).
h2. Proposed fix

Do not log the raw bearer token. On validation failure, log only non-sensitive
metadata needed for diagnosis, for example:
 * subject, audience, issuer
 * keyId (JWS header kid)
 * jwtId
 * tokenHash (SHA-256 of bearer string for log correlation only)
 * optional: failure reason (expired / signature / audience / issuer)

Example log line after fix:
{{JWT validation failed (subject=..., audience=..., issuer=..., keyId=..., 
jwtId=..., tokenHash=...)}}
h2. Backport targets
 *  master / 3.0
 *  ranger-2.9

  was:
h2. Summary

Apache Ranger's JWT authentication handler ({{{}RangerJwtAuthHandler{}}}) logs 
the full
serialized JWT bearer token (header.payload.signature) at WARN level when token
validation fails. For some failure modes—especially audience mismatch after a
valid signature and unexpired token—the logged credential remains live and can 
be
replayed against another Ranger JWT endpoint that trusts the same signing 
material
and accepts the token's audience.
h2. Reporter

Andrew Rukin (Arenadata) — reported via ASF Security Team (private disclosure).
Classification: CWE-532 (Insertion of Sensitive Information into Log File).
h2. Affected component
 * Module: {{ranger-authn}}
 * Class: {{org.apache.ranger.authz.handler.jwt.RangerJwtAuthHandler}}
 * Method: {{authenticate(String jwtAuthHeader)}} — validation-failure WARN path
 * Also used via: {{RangerDefaultJwtAuthHandler}} (Admin, PDP, audit paths, 
etc.)

h2. Affected versions

Verified on Apache Ranger 2.8.0. Same pattern present on ranger-2.8, ranger-2.9,
and master at time of report.
h2. Problem

On validation failure, the handler logs:
{{jwtToken.serialize()}}
which writes the complete bearer credential to operational logs.

{{validateToken()}} checks claims in order: expiration → signature → audience → 
issuer.
A cryptographically valid, unexpired token rejected only for audience mismatch 
still
hits the WARN branch and is logged in full.
h2. Impact

An actor with read access to Ranger operational logs (operators, log 
aggregation,
log storage) can recover a live JWT from a WARN entry and replay it against 
another
Ranger JWT consumer configured for that token's audience, authenticating as the
token subject.

This is not limited to malformed or unsigned tokens; reporter verified with a 
valid
RS256-signed JWT and future expiration.
h2. Root cause

{{RangerJwtAuthHandler.authenticate()}} logs the raw serialized token when
{{validateToken()}} returns false (historically around line 128 on master).
h2. Proposed fix

Do not log the raw bearer token. On validation failure, log only non-sensitive
metadata needed for diagnosis, for example:
 * subject, audience, issuer
 * keyId (JWS header kid)
 * jwtId
 * tokenHash (SHA-256 of bearer string for log correlation only)
 * optional: failure reason (expired / signature / audience / issuer)

Example log line after fix:
{{JWT validation failed (subject=..., audience=..., issuer=..., keyId=..., 
jwtId=..., tokenHash=...)}}
 
Out of scope / already OK
Other JWT-related filters ({{{}RangerSSOAuthenticationFilter{}}}, 
{{{}RangerJwtAuthFilter{}}},
{{{}JwtAuthNHandler{}}}, {{{}AuditJwtAuthFilter{}}}) log failure reasons 
without serializing
the full token. Primary fix is in {{{}RangerJwtAuthHandler{}}}.
h2. Test plan
 *  Unit test: {{safeJwtLogContext}} includes metadata and does not contain raw
token, header, payload, or signature segments
 *  Integration/runtime test (reporter harness): valid signed JWT with audience
{{service-a}} sent to handler configured for {{service-b}} → rejected, WARN log
does not contain full serialized JWT; same token accepted by handler for
{{service-a}} (confirms pre-fix replay scenario is closed for logs)
 *  {{mvn -pl ranger-authn test}}
 *  Checkstyle/PMD on changed files
 *  Backport verification on 2.8.x and 2.9.x branches

h2. Backport targets
 *  master / 3.0
 *  ranger-2.9

h2. Security / disclosure
 * Treat as security issue until ASF coordinated disclosure
 * CVE requested by reporter if confirmed
 * Credit in advisory: *Andrew Rukin (Arenadata)*
 * Do not discuss on public mailing lists until disclosure window

h2. References
 * Reporter verification: Apache Ranger 2.8.0 with local JWKS + RS256 test key
 * ASF Security forwarded report (Step 3); PMC Step 4 resolution pending
 * Production hardening doc (does not cover log confidentiality):
[https://cwiki.apache.org/confluence/display/RANGER/Lock+down+Apache+Ranger+for+production+deployments]


> RangerJwtAuthHandler logs full JWT bearer token on validation failure 
> (CWE-532)
> -------------------------------------------------------------------------------
>
>                 Key: RANGER-5693
>                 URL: https://issues.apache.org/jira/browse/RANGER-5693
>             Project: Ranger
>          Issue Type: Task
>          Components: Ranger, ranger-authn
>    Affects Versions: 2.8.0
>            Reporter: Ramachandran Krishnan
>            Assignee: Ramachandran Krishnan
>            Priority: Major
>             Fix For: 3.0.0, 2.9.0
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> h2. Summary
> Apache Ranger's JWT authentication handler ({{{}RangerJwtAuthHandler{}}}) 
> logs the full
> serialized JWT bearer token (header.payload.signature) at WARN level when 
> token
> validation fails. For some failure modes—especially audience mismatch after a
> valid signature and unexpired token—the logged credential remains live and 
> can be
> replayed against another Ranger JWT endpoint that trusts the same signing 
> material
> and accepts the token's audience.
> h2. Affected component
>  * Module: {{ranger-authn}}
>  * Class: {{org.apache.ranger.authz.handler.jwt.RangerJwtAuthHandler}}
>  * Method: {{authenticate(String jwtAuthHeader)}} — validation-failure WARN 
> path
>  * Also used via: {{RangerDefaultJwtAuthHandler}} (Admin, PDP, audit paths, 
> etc.)
> h2. Affected versions
> Verified on Apache Ranger 2.8.0. Same pattern present on ranger-2.8, 
> ranger-2.9,
> and master at time of report.
> h2. Problem
> On validation failure, the handler logs:
> {{jwtToken.serialize()}}
> which writes the complete bearer credential to operational logs.
> {{validateToken()}} checks claims in order: expiration → signature → audience 
> → issuer.
> A cryptographically valid, unexpired token rejected only for audience 
> mismatch still
> hits the WARN branch and is logged in full.
> h2. Impact
> An actor with read access to Ranger operational logs (operators, log 
> aggregation,
> log storage) can recover a live JWT from a WARN entry and replay it against 
> another
> Ranger JWT consumer configured for that token's audience, authenticating as 
> the
> token subject.
> This is not limited to malformed or unsigned tokens; reporter verified with a 
> valid
> RS256-signed JWT and future expiration.
> h2. Root cause
> {{RangerJwtAuthHandler.authenticate()}} logs the raw serialized token when
> {{validateToken()}} returns false (historically around line 128 on master).
> h2. Proposed fix
> Do not log the raw bearer token. On validation failure, log only non-sensitive
> metadata needed for diagnosis, for example:
>  * subject, audience, issuer
>  * keyId (JWS header kid)
>  * jwtId
>  * tokenHash (SHA-256 of bearer string for log correlation only)
>  * optional: failure reason (expired / signature / audience / issuer)
> Example log line after fix:
> {{JWT validation failed (subject=..., audience=..., issuer=..., keyId=..., 
> jwtId=..., tokenHash=...)}}
> h2. Backport targets
>  *  master / 3.0
>  *  ranger-2.9



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to