Skip to content

Add security considerations to the RoutingAppender documentation #4181

Description

@h4xr

Description

Currently RoutingAppender based on its configuration can materialize an unbounded number of routes. This coupled with a user controlled or high cardinality key can result in File descriptor exhaustion.

Example configuration which can be problematic:

<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="WARN">

    <Appenders>

        <Routing name="Routing">

            <Routes pattern="${ctx:userId}">

                <Route>

                    <File name="File-${ctx:userId}" fileName="logs/user-${ctx:userId}.log">

                        <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>

                    </File>

                </Route>

            </Routes>

            <IdlePurgePolicy timeToLive="10" cleanupIntervalMillis="1000"/>

        </Routing>

        <Console name="Console" target="SYSTEM_OUT">

            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>

        </Console>

    </Appenders>

    <Loggers>

        <Root level="info">

            <AppenderRef ref="Routing"/>

            <AppenderRef ref="Console"/>

        </Root>

    </Loggers>

</Configuration>

Configuration

Version: 2.26.3

Operating system: Mac OS 15

JDK: openjdk64-25.0.3

Logs

N/A

Reproduction

log4j config:

<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="WARN">

    <Appenders>

        <Routing name="Routing">

            <Routes pattern="${ctx:userId}">

                <Route>

                    <File name="File-${ctx:userId}" fileName="logs/user-${ctx:userId}.log">

                        <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>

                    </File>

                </Route>

            </Routes>

            <IdlePurgePolicy timeToLive="10" cleanupIntervalMillis="1000"/>

        </Routing>

        <Console name="Console" target="SYSTEM_OUT">

            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>

        </Console>

    </Appenders>

    <Loggers>

        <Root level="info">

            <AppenderRef ref="Routing"/>

            <AppenderRef ref="Console"/>

        </Root>

    </Loggers>

</Configuration>

Java Code to Trigger the bug:

import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.Logger;

import org.apache.logging.log4j.ThreadContext;

import java.util.UUID;


public class Harness {

    private static final Logger logger = LogManager.getLogger(Harness.class);


    public static void main(String[] args) {

        System.out.println("Starting DoS harness...");

        for (int i = 0; i < 1000000; i++) {

            String userId = UUID.randomUUID().toString();

            ThreadContext.put("userId", userId);

            [logger.info](http://logger.info/)("Log message for user: " + userId);

            if (i % 10000 == 0) {

                System.out.println("Logged " + i + " unique users...");

            }

        }

        System.out.println("Finished logging.");

    }

}

Detected using Decypher

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationPull requests or issues that affect documentation

    Type

    No type

    Projects

    Status
    Ready

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions