[ 
https://issues.apache.org/jira/browse/KAFKA-20921?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18115475#comment-18115475
 ] 

GiminKim edited comment on KAFKA-20921 at 9/15/26 8:54 AM:
-----------------------------------------------------------

Scope narrowed during review of PR #23128 
(https://github.com/apache/kafka/pull/23128#discussion_r4008394035). Defensive 
copying of the {{ScramCredentialData}} byte arrays was considered but withdrawn 
to follow the existing metadata ownership convention; this does not make those 
arrays immutable. This issue and PR now cover only {{ScramImage}}'s outer and 
nested mechanism maps.


was (Author: JIRAUSER314193):
Scope narrowed during review of PR #23128 
(https://github.com/apache/kafka/pull/23128#discussion_r4008394035). Defensive 
copying of the `ScramCredentialData` byte arrays was considered but withdrawn 
to follow the existing metadata ownership convention; this does not make those 
arrays immutable. This issue and PR now cover only `ScramImage`'s outer and 
nested mechanism maps.

> ScramImage exposes mutable nested credential maps
> -------------------------------------------------
>
>                 Key: KAFKA-20921
>                 URL: https://issues.apache.org/jira/browse/KAFKA-20921
>             Project: Kafka
>          Issue Type: Bug
>          Components: kraft
>         Environment: Apache Kafka trunk at 
> 2225a16c7e2658b4db207c89c477693373a52073 (4.4.0-SNAPSHOT)
>            Reporter: GiminKim
>            Assignee: GiminKim
>            Priority: Major
>
> h3. Problem
> {{ScramImage}} documents itself as thread-safe, but its constructor 
> previously wrapped only the outer mechanisms map with 
> {{Collections.unmodifiableMap}} without copying it. The nested per-mechanism 
> credential maps remained mutable. A caller could clear a nested map returned 
> by {{mechanisms()}} and remove SCRAM users from an already constructed image.
> {code:java}
> image.mechanisms()
>     .get(ScramMechanism.SCRAM_SHA_256)
>     .clear();
> {code}
> {{ScramDelta.apply()}} supplies mutable nested {{HashMap}} instances to 
> {{ScramImage}}. Changes to maps supplied to the constructor can also alter an 
> existing image.
> h3. Impact
> The contents of a SCRAM metadata image can change after construction through 
> its returned nested maps, rather than through a metadata update. This 
> violates the image's intended snapshot semantics. No remote mutation path is 
> currently known.
> h3. Expected behavior
> * The outer mechanisms map and every nested credential map are immutable 
> snapshots.
> * Mutating constructor input maps or maps returned from {{mechanisms()}} does 
> not alter an existing image.
> h3. Proposed fix
> * Snapshot-copy and make immutable the outer and nested maps in 
> {{ScramImage}}.
> * Add regression tests for constructor input changes and returned-map 
> mutation.
> Scope: Defensive copying of {{ScramCredentialData}} byte arrays was 
> considered during review but is intentionally not part of this issue. 
> Credential array behavior is unchanged under the existing metadata ownership 
> convention.
> Related work: KAFKA-19305 mentioned {{ScramImage}} immutability, but PR 
> #19847 only updated {{ClientQuotaImage}} and {{TopicImage}}.



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

Reply via email to