diff --git a/configuration/buffer-section.md b/configuration/buffer-section.md index f78a0ba5..28ec067d 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 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 `\`\): + +```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..b2cbb19d 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}` 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. + ### `#commit_write(chunk_id)` It tells Fluentd that the specified chunk should be committed. That chunk will be purged after this method call.