From 784e3ed1dc6a2dfc26b41eb8f5c75f527b1be6a4 Mon Sep 17 00:00:00 2001 From: Shizuo Fujita Date: Thu, 16 Jul 2026 16:06:35 +0900 Subject: [PATCH 1/2] output: apply to change `extract_placeholders()` API behavior Signed-off-by: Shizuo Fujita --- configuration/buffer-section.md | 24 +++++++++++++++++++++++- plugin-development/api-plugin-output.md | 4 ++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/configuration/buffer-section.md b/configuration/buffer-section.md index f78a0ba5..04b27a97 100644 --- a/configuration/buffer-section.md +++ b/configuration/buffer-section.md @@ -278,6 +278,29 @@ Any key is acceptable as a chunk key. If a key other than specified in the chunk ``` +### Path Boundary Validation + +Since v1.19.3, Fluentd validates the values substituted into `${tag}` and `${key}` placeholders so that they cannot cross an unintended path boundary. Because tags and record fields come from incoming events, an unexpected event could otherwise make a plugin like `out_file` create or access a file outside of the intended directory. + +A value is rejected if it contains a parent directory reference \(`../` or `..\`\) or if it begins with a path separator \(`/` or `\`\): + +```text +# tag: "../etc/cron.d" or "/etc/passwd" + + @type file + path /data/${tag}/access.log #=> Fluent::UnrecoverableError + + # ... + + +``` + +The validation also detects the case where an invalid component appears only after the substitution, e.g. `${a}${b}` where `a` is `.` and `b` is `./`. A `../` written in the configuration itself is not affected. + +`Fluent::UnrecoverableError` is raised when the validation fails, so the chunk is not retried. It is moved to `secondary` or the backup directory. See [Handling Unrecoverable Errors](../buffer/#handling-unrecoverable-errors). + +Note that this validation is applied only where a placeholder is actually used. A tag containing `../` is harmless as long as the target parameter has no `${tag}` placeholder. + ### Chunk ID `${chunk_id}` will be replaced with internal chunk id. No need to specify `chunk_id` in chunk keys. @@ -582,4 +605,3 @@ With `exponential_backoff`, `retry_wait` interval will be calculated as below: * = `2^k - 1` by default If this article is incorrect or outdated, or omits critical information, please [let us know](https://github.com/fluent/fluentd-docs-gitbook/issues?state=open). [Fluentd](http://www.fluentd.org/) is an open-source project under [Cloud Native Computing Foundation \(CNCF\)](https://cncf.io/). All components are available under the Apache 2 License. - diff --git a/plugin-development/api-plugin-output.md b/plugin-development/api-plugin-output.md index b6950c1b..68a24796 100644 --- a/plugin-development/api-plugin-output.md +++ b/plugin-development/api-plugin-output.md @@ -346,6 +346,10 @@ It extracts placeholders in the given string using the values in chunk. Return value is a `String`. +Since v1.19.3, this method raises `Fluent::UnrecoverableError` if a value substituted into `${tag}` or `${key}` would cross a path boundary, e.g. a tag containing `../` or beginning with `/`. See [Path Boundary Validation](../configuration/buffer-section.md#path-boundary-validation). + +Since the check lives in this method, every plugin using it is protected without any change. If your plugin builds paths from tags or record fields on its own, without `#extract_placeholders`, you need to validate them yourself. + ### `#commit_write(chunk_id)` It tells Fluentd that the specified chunk should be committed. That chunk will be purged after this method call. From 7df3ff9afe85232bd78f9ad805e61b4b540851e4 Mon Sep 17 00:00:00 2001 From: Shizuo Fujita Date: Fri, 17 Jul 2026 14:06:22 +0900 Subject: [PATCH 2/2] Update Co-authored-by: Kentaro Hayashi Signed-off-by: Shizuo Fujita --- configuration/buffer-section.md | 2 +- plugin-development/api-plugin-output.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configuration/buffer-section.md b/configuration/buffer-section.md index 04b27a97..28ec067d 100644 --- a/configuration/buffer-section.md +++ b/configuration/buffer-section.md @@ -280,7 +280,7 @@ Any key is acceptable as a chunk key. If a key other than specified in the chunk ### Path Boundary Validation -Since v1.19.3, Fluentd validates the values substituted into `${tag}` and `${key}` placeholders so that they cannot cross an unintended path boundary. Because tags and record fields come from incoming events, an unexpected event could otherwise make a plugin like `out_file` create or access a file outside of the intended directory. +Since v1.19.3, Fluentd validates the values substituted into `${tag}` and `${key}` placeholders to prevent unintended path traversal. Because tags and record fields come from incoming events, an unexpected event could otherwise make a plugin like `out_file` create or access a file outside of the intended directory. A value is rejected if it contains a parent directory reference \(`../` or `..\`\) or if it begins with a path separator \(`/` or `\`\): diff --git a/plugin-development/api-plugin-output.md b/plugin-development/api-plugin-output.md index 68a24796..b2cbb19d 100644 --- a/plugin-development/api-plugin-output.md +++ b/plugin-development/api-plugin-output.md @@ -346,7 +346,7 @@ It extracts placeholders in the given string using the values in chunk. Return value is a `String`. -Since v1.19.3, this method raises `Fluent::UnrecoverableError` if a value substituted into `${tag}` or `${key}` would cross a path boundary, e.g. a tag containing `../` or beginning with `/`. See [Path Boundary Validation](../configuration/buffer-section.md#path-boundary-validation). +Since v1.19.3, this method raises `Fluent::UnrecoverableError` if a value substituted into `${tag}` or `${key}` attempts a path traversal, e.g. a tag containing `../` or beginning with `/`. See [Path Boundary Validation](../configuration/buffer-section.md#path-boundary-validation). Since the check lives in this method, every plugin using it is protected without any change. If your plugin builds paths from tags or record fields on its own, without `#extract_placeholders`, you need to validate them yourself.