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

Brad Schoening commented on CASSANDRA-21755:
--------------------------------------------

[~smiklosovic] STARTUP options are sent before authentication, so any client 
that can reach the native port can send them. Today, the only bound on that 
payload is {{{}native_transport_max_frame_size{}}}, 16 MiB by default. The 
server also keeps the options for the life of the connection 
({{{}ClientState.setClientOptions{}}}) and exposes them in 
{{{}system_views.clients{}}}. So an unauthenticated client can make the server 
hold up to 16 MiB per connection, multiplied by however many connections it 
opens.

The main goal of this patch is to close that gap by bounding the size of 
STARTUP options.

> NTR STARTUP options are retained and exposed (system_views.clients, nodetool 
> clientstats, JMX) before authentication, with no sanitization or size limits
> ---------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CASSANDRA-21755
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21755
>             Project: Apache Cassandra
>          Issue Type: Bug
>          Components: Observability/JMX
>            Reporter: Brad Schoening
>            Assignee: Rishabh Saraswat
>            Priority: Normal
>          Time Spent: 4.5h
>  Remaining Estimate: 0h
>
> The native protocol STARTUP message carries a {{[string map]}} of options. 
> The server
> accepts and retains the entire map up to {{native_transport_max_frame_size}} 
> (16 MB by default)— including keys it does not recognize — and exposes it to 
> operators via {{system_views.clients}} ({{{}client_options{}}}), {{{}nodetool 
> clientstats{}}}, and
> the JMX client metrics.
> This happens {*}before authentication{*}. The connection is registered in the 
> connection tracker when STARTUP is processed (via the {{Connection}} 
> constructor →
> {{{}ConnectionTracker.addConnection{}}}), and {{StartupMessage.execute()}} 
> calls
> {{ClientState.setClientOptions(options)}} before the authentication challenge 
> is issued. As a result, an unauthenticated client controls data that appears 
> in operator-facing views for as long as it keeps the socket open, whether or 
> not it ever presents valid credentials.
> The retained values are also neither sanitized nor bounded:
>  * Strings are decoded as UTF-8 but are otherwise unconstrained — control 
> characters,
> newlines, and terminal escape sequences are all accepted.
>  * {{ConnectedClient.asMap()}} (which feeds {{nodetool clientstats}} and JMX) 
> joins the entries as {{k=v, k=v}} with no escaping, so a value containing 
> {{", foo=bar"}} is
> indistinguishable from a separate option in that output.
>  * There is no limit on key/value length, on the number of entries, or on 
> duplicate keys,
> beyond the overall {{native_transport_max_frame_size}} (16 MB by default).
> h3. Steps to reproduce
>  # Open a native protocol connection and send a STARTUP message with a 
> populated options map
> (optionally including a non-printable character or a {{", k=v"}} fragment in 
> a value).
>  # Do *not* complete authentication — leave the connection open at the 
> authenticating stage.
>  # Observe the connection in operator views.
> {noformat}
> % nodetool clientstats --all
> Address          SSL   Cipher    Protocol  Version User      Keyspace 
> Requests Driver-Name Driver-Version
> /127.0.0.1:51690 false undefined undefined 3       anonymous          1       
>  undefined   undefined
> {noformat}
> The same connection appears in {{system_views.clients}} with its 
> {{client_options}}
> populated and {{connection_stage}} = {{{}authenticating{}}}.
> h3. Expected behaviour
> Client-supplied STARTUP options should be constrained before being 
> retained/displayed, and skip display of un-authenticed clients or, 
> alternatively, option paths should not be able to carry control characters or 
> forge delimiter structure.
> h3. Proposed hardening
> Aggressively sanitize and limit size of options since these are sent before 
> authentication. 
> Deferring {{setClientOptions()}} (and option retention generally) until after 
> successful
> authentication would additionally remove the unauthenticated-exposure aspect.
> For one approach, see the Postgres 
> [pg_clean_ascii()|https://github.com/ryogrid/create_pg_super_document/blob/master/generated_docs/p/pg_clean_ascii.md]
>  which sanitizes startup options for display with 
> [pg_stat_activity()|https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW]



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to