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

ASF GitHub Bot updated FLINK-40414:
-----------------------------------
    Labels: pull-request-available  (was: )

> Autoscaler state ConfigMap is treated as trusted input
> ------------------------------------------------------
>
>                 Key: FLINK-40414
>                 URL: https://issues.apache.org/jira/browse/FLINK-40414
>             Project: Flink
>          Issue Type: Bug
>          Components: Autoscaler, Kubernetes Operator
>            Reporter: Dennis-Mircea Ciupitu
>            Priority: Major
>              Labels: pull-request-available
>
> h1. Summary
> The autoscaler persists its state in a per-resource ConfigMap 
> ({{autoscaler-<name>}}): scaling history, collected metrics, scaling 
> tracking, delayed scale-down, parallelism overrides and config overrides. The 
> operator reads that ConfigMap back on every cycle and acts on its contents, 
> but treats it as trusted input. The ConfigMap is writable by any workload in 
> the namespace, so a poisoned or corrupt entry can break a reconcile or 
> influence a managed deployment.
> h1. Trust boundary
> The autoscaler state ConfigMap is created and owned by the operator, but the 
> default Flink job Role grants the job service account 
> {{create/update/patch/delete}} on {{configmaps}} in its namespace (required 
> for Kubernetes HA). Tenant code running in a TaskManager or JobManager pod 
> can therefore write any ConfigMap in the namespace, including the autoscaler 
> state of another job.
> Among the ConfigMaps the operator handles, only the autoscaler state 
> ConfigMap has its content deserialized and acted upon. The generated cluster 
> config and pod-template ConfigMaps are write-only from the operator, and the 
> Kubernetes HA ConfigMaps are read only by name and key presence, never by 
> value. The autoscaler state ConfigMap is the operator's untrusted-input 
> surface.
> h1. Problems
> h2. Reads are not uniformly fail-closed
> The six read paths handle a bad stored value inconsistently:
> * {{getParallelismOverrides}} has no error handling. A malformed value throws 
> out of the read and into the reconcile loop.
> * {{getConfigChanges}} falls back to empty on a bad value but does not 
> discard the poisoned entry, so it is re-read and re-parsed every cycle.
> * The remaining four discard the bad entry and fall back to empty.
> So the same class of input is variously ignored, re-read, or allowed to 
> propagate an exception.
> h2. Config overrides are applied to the deployment spec unfiltered
> When memory tuning is enabled, the config overrides read from the ConfigMap 
> are merged into {{spec.flinkConfiguration}} with no key filtering. A poisoned 
> entry can therefore inject arbitrary Flink configuration, for example 
> {{env.java.opts}} or a pod template, into a managed deployment. This is an 
> escalation from "write one ConfigMap" to influencing how and what the managed 
> cluster runs, potentially across jobs within a namespace.
> h2. No value sanity
> Values read from the ConfigMap, such as the per-vertex parallelism overrides, 
> are applied without basic validity checks.
> h1. Impact
> * Integrity and availability: a crafted entry can break a reconcile through 
> an unhandled exception, or feed the autoscaler bogus history and metrics that 
> steer scaling for that job or a co-tenant.
> * Config injection: with memory tuning enabled, arbitrary Flink configuration 
> reaches the managed deployment spec.
> * Current exposure is bounded by {{job.autoscaler.memory.tuning.enabled}} 
> (default off) for the injection path, but the design flaw is independent of 
> that flag.
> This is not a deserialization remote-code-execution issue. The mapper uses no 
> default typing and binds to concrete types, so malformed input fails to bind 
> rather than instantiating arbitrary classes. The risk is integrity, 
> availability and config injection.
> h1. Scope
> This completes the autoscaler-adjacent security review alongside FLINK-40400 
> (artifact fetch SSRF) and FLINK-40401 (decompression bomb on the compressed 
> state fields). Those two harden individual fields or paths as issues 
> surfaced. This item addresses the general untrusted-read boundary of the 
> state ConfigMap so the class of problem is closed rather than one instance.
> h1. Proposed approach
> At a high level:
> * Treat every read from the autoscaler state ConfigMap as untrusted: 
> deserialize uniformly and fail closed, discarding the offending entry and 
> falling back to empty on any failure, plus light value sanity on the values 
> that are applied.
> * Filter config overrides on apply against the set of keys memory tuning is 
> actually allowed to set, so that only memory-tuning keys can reach the 
> deployment spec.
> Out of scope: deeper hardening of scaling decisions against plausible but 
> wrong metrics, and the decompression size bound owned by FLINK-40401.



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

Reply via email to