This is an automated email from the ASF dual-hosted git repository.
github-actions[bot] pushed a commit to branch 2.x-site-stg-out
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/2.x-site-stg-out by this push:
new f67ec6c414 Add website content generated from
`33c8236d880ab05539e18ec3d7c45fe941ec1639`
f67ec6c414 is described below
commit f67ec6c414f52b1b4147dd7fa1082ef9fbd22adb
Author: ASF Logging Services RM <[email protected]>
AuthorDate: Thu Aug 27 16:48:30 2026 +0000
Add website content generated from
`33c8236d880ab05539e18ec3d7c45fe941ec1639`
---
manual/appenders/delegating.html | 85 ++++++++++++++++++++++++++-
plugin-reference.html | 2 +-
release-notes.html | 3 +
sitemap.xml | 120 +++++++++++++++++++--------------------
4 files changed, 148 insertions(+), 62 deletions(-)
diff --git a/manual/appenders/delegating.html b/manual/appenders/delegating.html
index 042ecc7b70..84a69c9e67 100644
--- a/manual/appenders/delegating.html
+++ b/manual/appenders/delegating.html
@@ -1836,7 +1836,7 @@ The appender can be:</p>
</li>
<li>
<p>A new appender that is instantiated based on a nested appender definition,
when the route becomes active.
-See also <a href="#PurgePolicy">Purge Policy</a> to learn more about the
lifecycle of such an appender.</p>
+See also <a href="#PurgePolicy">Purge Policy</a> to learn more about the
lifecycle of such an appender, and <a href="#RoutingAppender-security">Security
considerations</a> before deriving the key from request data.</p>
</li>
</ul>
</div>
@@ -1969,6 +1969,89 @@ This means that <code>${...}</code> expression
<strong>should not</strong> be es
</div>
</div>
<div class="sect2">
+<h3 id="RoutingAppender-security"><a class="anchor"
href="#RoutingAppender-security"></a>Security considerations</h3>
+<div class="paragraph">
+<p>When a default <a href="#Route"><code>Route</code></a> embeds an appender
definition, the <code>Routing</code> Appender creates <strong>one subordinate
appender per distinct routing key value</strong>.
+Unlike most appenders, which are fully built when the configuration is loaded,
those subordinate appenders are created <strong>at runtime</strong> when a new
key appears.
+Lookups used in the route (for example <code>${ctx:userId}</code>) can
therefore still carry attacker-controlled data when appender attributes are
resolved.</p>
+</div>
+<div class="paragraph">
+<p>Review two aspects of any dynamic routing configuration:</p>
+</div>
+<div class="sect3">
+<h4 id="RoutingAppender-security-resources"><a class="anchor"
href="#RoutingAppender-security-resources"></a>Resource allocation</h4>
+<div class="paragraph">
+<p>The <code>Routing</code> Appender is intentionally powerful: a separate log
file per tenant or per long-running job, or round-robin routing between a fixed
set of appenders, are all supported designs.
+The responsibility that comes with that power is provisioning: the system must
be able to allocate the resources required by every appender that can be
created.</p>
+</div>
+<div class="paragraph">
+<p>If the key is derived from untrusted or high-cardinality data (for example
<code>${ctx:userId}</code>, a client IP, or a free-form request header), an
attacker or a busy system can force creation of an unbounded number of
appenders.</p>
+</div>
+<div class="paragraph">
+<p>That growth commonly leads to:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>exhaustion of file descriptors (when each route opens a <code>File</code>
or rolling file appender)</p>
+</li>
+<li>
+<p>elevated memory use for appender state, buffers, and managers</p>
+</li>
+<li>
+<p>difficulty shutting down or reconfiguring the application cleanly</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect3">
+<h4 id="RoutingAppender-security-threat-model"><a class="anchor"
href="#RoutingAppender-security-threat-model"></a>Threat model</h4>
+<div class="paragraph">
+<p>An untrusted key is not only a resource problem: it is also substituted
into the subordinate appender’s configuration.
+Attributes such as <code>fileName</code> therefore inherit whatever the lookup
returns.</p>
+</div>
+<div class="paragraph">
+<p>For example, with <code>fileName="logs/${ctx:userId}.log"</code>, a Thread
Context value of <code>../../../../tmp/x</code> (as a whole path segment) can
open <code>/tmp/x.log</code> without an error.
+Embedding the lookup inside a longer fixed segment, such as
<code>logs/user-${ctx:userId}.log</code>, usually fails to open the file
instead of escaping the directory, so the exact <code>fileName</code> pattern
matters.
+That failure is a side effect of how paths are resolved, not a mitigation: it
is loud rather than safe, and it does not hold for every value a lookup can
return.
+The appender is also re-attempted, and the event lost, on every subsequent
event with that key.</p>
+</div>
+<div class="paragraph">
+<p>This matches the project’s <a
href="https://logging.apache.org/security.html#threat-common-sources-configuration">threat
model for configuration sources</a>: operators are responsible for ensuring
that appender configuration attributes come from trusted data.
+Only the application developer knows which Thread Context keys carry validated
values and which are entirely attacker-controlled.
+See also <a
href="https://logging.apache.org/security/faq.html#path-traversal">path
traversal in the security FAQ</a>.</p>
+</div>
+<div class="paragraph">
+<p>The same substitution reaches non-file sinks: a <code>Route</code> that
builds an <a href="network.html#HttpAppender" class="xref page">HTTP
Appender</a> interpolates the key into its <code>url</code>, turning an
untrusted routing key into a server-side request forgery (SSRF) vector.</p>
+</div>
+</div>
+<div class="sect3">
+<h4 id="RoutingAppender-security-mitigations"><a class="anchor"
href="#RoutingAppender-security-mitigations"></a>Mitigations</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>Prefer the <a href="#Route-attr-ref"><code>ref</code> attribute</a> of a
<code>Route</code>, pointing at a fixed, predeclared set of appenders, when the
set of destinations is known.</p>
+</li>
+<li>
+<p>When dynamic routes are required, always configure a <a
href="#PurgePolicy"><code>PurgePolicy</code></a> (typically <a
href="#IdlePurgePolicy"><code>IdlePurgePolicy</code></a>) so idle route
appenders are stopped and released.</p>
+<div class="paragraph">
+<p>Note that a purge policy bounds how long an unused appender survives, not
the rate at which new ones are created.</p>
+</div>
+</li>
+<li>
+<p>Constrain routing keys to a low-cardinality, validated domain (allow-lists,
enums, hashed buckets) instead of raw user input.</p>
+</li>
+<li>
+<p>Avoid routing on pure user-controlled identifiers when each value would
create a new file-backed appender, or when the key is interpolated into paths,
URLs, or other sink configuration.</p>
+</li>
+<li>
+<p>Do not create an appender per web request. <a
href="../api.html#fish-tagging" class="xref page">Fish tagging</a> the events
and filtering on the tag is a far better use of resources.</p>
+</li>
+</ul>
+</div>
+</div>
+</div>
+<div class="sect2">
<h3 id="PurgePolicy"><a class="anchor" href="#PurgePolicy"></a>Purge
Policy</h3>
<div class="paragraph">
<p>If your default <a href="#Route"><code>Route</code> element</a> contains an
<a href="#Route-element-Appender">appender definition</a>, the
<code>Routing</code> Appender can instantiate a large number of appenders, one
for each value of the routing key.
diff --git a/plugin-reference.html b/plugin-reference.html
index d186dcbd56..2f71fcd52b 100644
--- a/plugin-reference.html
+++ b/plugin-reference.html
@@ -1479,7 +1479,7 @@ Originally developed by Ceki Glc and Anders
Kristensen.</p>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>header</code></p></td>
-<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>String?</code></p></td>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>boolean?</code></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><div class="content"></div></td>
</tr>
diff --git a/release-notes.html b/release-notes.html
index dc95589651..233daf8ff7 100644
--- a/release-notes.html
+++ b/release-notes.html
@@ -414,6 +414,9 @@
<p>Fix properties configuration format to correctly parse and apply nested
custom properties on loggers and root loggers (<a
href="https://github.com/apache/logging-log4j2/issues/4024">4024</a>, <a
href="https://github.com/apache/logging-log4j2/pull/4142">4142</a>)</p>
</li>
<li>
+<p>Document security considerations for high-cardinality keys with the
<code>Routing</code> Appender (<a
href="https://github.com/apache/logging-log4j2/issues/4181">4181</a>)</p>
+</li>
+<li>
<p>Fix exceptions in JMX integration (<a
href="https://github.com/apache/logging-log4j2/pull/4185">4185</a>)</p>
</li>
<li>
diff --git a/sitemap.xml b/sitemap.xml
index 8b75ebad27..6f759d228c 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -2,242 +2,242 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://logging.apache.org/log4j/2.x/components.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/development.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/download.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/faq.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/graalvm.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/hibernate.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/index.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/jakarta.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/javadoc.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/log4j-iostreams.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/log4j-jul.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/log4j-spring-boot.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/log4j-spring-cloud-config-client.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/log4j-to-jul.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/api.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/appenders.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/appenders/database.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/appenders/delegating.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/appenders/file.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/appenders/message-queue.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/appenders/network.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/appenders/rolling-file.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/architecture.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/async.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/compatibility.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/config-intro.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/configuration.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/customconfig.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/customloglevels.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/eventlogging.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/extending.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/filters.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/flowtracing.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/garbagefree.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/getting-started.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/implementation.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/index.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/installation.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/jmx.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/json-template-layout.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/layouts.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/logbuilder.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/lookups.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/markers.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/messages.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/pattern-layout.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/performance.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/plugins.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/scripts.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/simple-logger.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/status-logger.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/systemproperties.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/manual/thread-context.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/migrate-from-log4j1.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/migrate-from-logback.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/migrate-from-slf4j.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/plugin-reference.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/release-notes.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/soa.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/2.x/versioning.html</loc>
-<lastmod>2026-08-27T15:42:17.299Z</lastmod>
+<lastmod>2026-08-27T16:47:53.428Z</lastmod>
</url>
</urlset>