Jul 29, 2026·7 min read·125 visits
Authenticated users with Flow or ClusterFlow creation rights can inject newlines into Logging Operator Custom Resources, enabling downstream Fluentd configuration manipulation and arbitrary command execution.
A critical security flaw (CVE-2026-54680) in the Kubernetes Logging Operator allows authenticated attackers with namespace-level access to craft malicious Custom Resources that inject arbitrary configuration directives into the downstream Fluentd logging aggregator, resulting in unauthenticated remote code execution (RCE) in the context of the aggregator pod.
The Kubernetes Logging Operator manages log collection pipelines by dynamically orchestrating Fluentd and Fluentbit instances. The central component of this operator is responsible for compiling high-level declarative Custom Resources (CRDs), such as Flow and ClusterFlow, into raw, functional configurations loaded by downstream collectors. Because of the nature of logging pipelines, the operator acts as a translation layer, processing configuration parameters from user-defined YAML declarations and organizing them into structured configuration files.
The critical attack surface is situated in how the operator processes user-controlled parameter values within the configuration renderer. Specifically, the component tasked with creating the fluent.conf file allows unvalidated strings to flow from Kubernetes API objects to the final plaintext configuration structure. If these parameters are not properly structured, they expose the parsing engine of the downstream Fluentd log aggregator.
This exposure manifests as a structural injection vulnerability, tracked as CWE-74 and CWE-77. Attackers with permission to modify or create Flow objects can manipulate the structure of the generated configuration file. Because the downstream Fluentd component possesses highly privileged plugin capabilities—such as executing external processes to transport or manipulate log messages—gaining control over its configuration is equivalent to achieving remote code execution inside the collector pod.
The core defect exists within the Fluentd configuration renderer FluentRender defined in the file pkg/sdk/logging/model/render/fluent.go. This rendering engine is responsible for writing structured key-value pairs representing custom filters, record transformers, and output destinations to the destination configuration stream. The engine relies on the indentedf helper function to format nested blocks, splitting incoming multi-line parameters by newline boundaries to maintain clean indentation.
Because the renderer handles input strings directly, it assumes that any newline character (\n or \r) represents an intended formatting decision rather than a malicious escape sequence. If an operator-defined CRD includes a parameter populated with arbitrary newline characters, the indentedf function outputs these raw boundaries directly into the final fluent.conf stream. This behavior breaks the configuration out of the expected nested block context.
An attacker can construct a payload that effectively terminates the active configuration block, closes the parent directives like <record> or <filter>, and injects top-level blocks. This direct block escape allows the registration of arbitrary Fluentd input, filter, or output plugins. By utilizing Fluentd's built-in @type exec plugin, an attacker can designate command-line tools to be executed upon the arrival of log streams, completing the path to system command execution.
The vulnerability lies in the lack of character validation and escaping during the translation from the Go structures representing Custom Resources to the raw configuration file.
Below is a logical flow representation of how the untrusted CRD input bypasses validation and alters the configuration structure.
Prior to the patch, indentedf processed strings using standard, unescaped formatting mechanisms:
// VULNERABLE RENDERER MECHANISM (fluent.go)
func (f *FluentRender) indentedf(indent int, format string, values ...interface{}) {
indentString := strings.Repeat(" ", indent)
in := fmt.Sprintf(format, values...)
// Raw string splitting without verifying whether 'line' breaks context boundaries
for _, line := range strings.Split(in, "\n") {
if line != "" {
fmt.Fprint(f.Out, indentString+line+"\n")
}
}
}To remediate this, the maintainers implemented two mechanisms in commit cf437d7f1e056c78740bf5716ac8bdebcf002425. The first is structural token validation to prevent newlines in directive structures. The second is an escaping and quoting wrapper for raw values:
// PATCHED SANITIZATION ENGINE
var fluentEscaper = strings.NewReplacer(
`\`, `\\`,
`"`, `\"`,
"\n", `\n`,
"\r", `\r`,
"\t", `\t`,
`#`, `\#`, // Escaping '#' neutralizes Ruby string interpolation
)
func escapeFluentValue(value string) string {
if !strings.ContainsAny(value, "\n\r") {
return value // Safe; no escape required
}
// Wrap with quotes and escape special characters
return `"` + fluentEscaper.Replace(value) + `"`
}The addition of the # character to the escaping list is a critical security measure. Fluentd evaluates double-quoted strings and supports embedded Ruby interpolation syntaxes like #{system('id')}. By escaping the # symbol into \#, the patch prevents attackers from bypassing the newline constraints to execute code via internal language evaluations.
To exploit this vulnerability, an attacker requires access permissions sufficient to create, modify, or patch Flow or ClusterFlow resources within a Kubernetes namespace managed by the Logging Operator. Because these resource actions are typical for developers managing their service logging configurations, this requirement matches a low-privilege threshold (PR:L).
The attacker initiates the exploit by defining a custom Flow and targeting the record_transformer filter plugin. The payload uses carriage returns and newlines to break out of the configuration scope. Below is an example representation of the malicious Custom Resource containing the injection payload:
apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: malicious-flow
namespace: default
spec:
filters:
- record_transformer:
records:
- inject_key: "safe_value\n</record>\n</filter>\n<match **>\n @type exec\n command id > /tmp/rce_output\n</match>"
globalOutputRefs:
- default-outputWhen the operator picks up this resource, it dynamically constructs the fluent.conf file. The output engine interprets the literal newlines as structural block endings, closing the <filter> declaration prematurly and creating an independent <match> block using the command execution plugin @type exec. The downstream Fluentd container parses the config file successfully, identifies the new configuration, and executes the designated command as soon as any log enters the system.
Successful exploitation of CVE-2026-54680 results in full command execution in the context of the running Fluentd aggregator pod. By default, the aggregator container executes with permissions and system mount scopes defined in the Kubernetes Deployment spec. In many default configurations, this container runs with substantial cluster access or contains credentials enabling communication with internal cluster resources.
An attacker operating within the Fluentd container can read and manipulate all log messages entering the pipeline, presenting a complete compromise of confidential business data and system logs. Sensitive fields—such as authentication tokens, passwords, and API keys leaked in log messages—can be extracted by the attacker. In addition, the attacker can use the container as a pivot point to perform network reconnaissance or execute attacks against the Kubernetes API.
The CVSS v3.1 score is evaluated at 9.9 (Critical), reflecting the low barrier to entry for users who already possess basic namespace permissions. The changed scope (Scope: Changed) highlights that the attack breaks out of the custom resource declaration context and executes commands inside the real operating system space of the host container. This can lead to service disruptions or manipulation of downstream log auditing solutions.
The primary remediation path requires upgrading the Logging Operator deployment to version 6.6.0 or later. This release incorporates the validation and escaping safeguards to neutralize any embedded newline characters and prevent configuration syntax hijacking.
For environments where an immediate operator update cannot be scheduled, administrators can implement defensive admission policies. Utilizing engines such as OPA Gatekeeper or Kyverno, teams can validate Custom Resources during the admission phase. The following Kyverno cluster policy blocks incoming resources containing potential injection syntax:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: block-fluentd-injection
spec:
validationFailureAction: Enforce
background: true
rules:
- name: block-newlines-in-records
match:
any:
- resources:
kinds:
- logging.banzaicloud.io/v1beta1/Flow
- logging.banzaicloud.io/v1beta1/ClusterFlow
validate:
message: "Carriage returns or newline characters are not permitted inside Flow records configurations to prevent command injection."
pattern:
spec:
filters:
- =(record_transformer):
records:
- inject_key: "!*[\n\r]*"Additionally, organizations should audit existing Flow, ClusterFlow, Output, and ClusterOutput Custom Resources for unexpected line feeds or structural escape patterns. Ensuring that Fluentd aggregator containers run as non-root users, utilizing read-only root filesystems, and removing access to the local service account token if unused will limit the post-exploitation capabilities of an attacker.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Logging Operator Kube-Logging | < 6.6.0 | 6.6.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-74, CWE-77 |
| Attack Vector | Network |
| CVSS Score | 9.9 (Critical) |
| Exploit Status | PoC Available |
| Scope | Changed |
| Privileges Required | Low |
| Impact | Remote Code Execution (RCE) |
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.
Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.
Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.
An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.
In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.
A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.