CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-1225

XML Ghosts in the Machine: Configuring Your Way to RCE in Logback

Amit Schendel
Amit Schendel
Senior Security Researcher

Jan 23, 2026·6 min read·107 visits

Executive Summary (TL;DR)

If an attacker can modify your `logback.xml`, they can trick the Joran engine into treating a non-existent appender reference as a fully qualified class name. Logback will then helpfully instantiate that class via reflection. While the CVSS is low due to the prerequisite of file write access, it serves as a powerful persistence or privilege escalation vector.

A logic flaw in the Joran configuration engine within Logback-core allows attackers with write access to configuration files to instantiate arbitrary classes via reflection, leading to code execution.

The Hook: It's 2026 and We're Still Doing This

Let's be honest: Java logging libraries are the gift that keeps on giving. Just when you thought the trauma of Log4Shell had faded into a dull ache, Logback—the 'safe' alternative—decided to hold our beer.

CVE-2026-1225 isn't a network-facing nuke like its predecessors. It’s quieter, more subtle, and frankly, a bit more embarrassing. It lives in Joran, Logback's internal configuration engine. Joran is responsible for parsing those sprawling logback.xml files that everyone copy-pastes from StackOverflow and turning them into live Java objects.

The problem? Joran is too helpful. It loves instantiation. It sees a string in an XML tag and thinks, 'I wonder if this is a class I can load?' In this specific case, the mechanism used to reference Appenders (the things that actually write logs to files or consoles) had a fallback logic so loose it might as well have been a try { eval() } catch { ignore }.

If you have write access to the config file, you don't just control the logs; you control the runtime. This vulnerability is a reminder that in the world of Java, 'configuration' is often just a euphemism for 'uncompiled code'.

The Flaw: A Case of Mistaken Identity

To understand the bug, you have to look at how Logback handles dependencies. When you define a logger in XML, you attach appenders to it using the <appender-ref> tag.

Typically, it looks like this:

<root level="info">
  <appender-ref ref="CONSOLE" />
</root>

Joran sees ref="CONSOLE" and looks up an appender named CONSOLE in its internal map. Simple, right? But what happens if Joran can't find an appender named CONSOLE?

In versions prior to 1.5.25, Joran’s DefaultProcessor and AppenderRefModelHandler got creative. Instead of strictly failing, the logic allowed for a fallback where the string provided in the ref attribute could be interpreted as a Fully Qualified Class Name (FQCN).

Why? Presumably for some dynamic dependency resolution feature lost to time. But practically, it meant that if I put <appender-ref ref="com.example.MyEvilClass" />, and an appender named com.example.MyEvilClass didn't exist, Joran would shrug and say, 'Well, maybe it's a class?' and attempt to instantiate it via reflection using the default constructor.

This is a classic 'Desirability vs. Security' trade-off failure. The engine prioritized making things work (resolving dependencies dynamically) over ensuring that only explicitly defined components were loaded.

The Code: Patching the Leak

The fix, landed in commit 1f97ae1844b1be8486e4e9cade98d7123d3eded5 by Ceki Gülcü, introduces a concept that should have probably been there from day one: Declaration Analysis.

The patch introduces a new component, AppenderDeclarationAnalyser. Before Joran tries to link anything up, this analyzer creates a strict allowlist (DECLARED_APPENDER_NAME_SET) of all appenders that are explicitly defined in the XML.

Here is a conceptual view of the change in AppenderRefModelHandler.java.

The Vulnerable Logic (Conceptual):

// Old, loose logic
String refName = attributes.getValue("ref");
Appender appender = appenderBag.get(refName);
 
if (appender == null) {
    // DANGER ZONE: The code might drift into attempting
    // to resolve 'refName' as a class later in the chain.
    dependencyQueue.add(refName);
}

The Fixed Logic:

// New, strict logic
String refName = attributes.getValue("ref");
 
// The Guard Clause
if (!isAppenderDeclared(mic, refName)) {
    addWarn("Appender named [" + refName + "] not declared. Skipping.");
    return; 
}
 
// Proceed only if it's a known, declared appender

By enforcing this check, the DefaultProcessor is prevented from ever reaching the fallback code paths that attempt reflection on arbitrary strings. If you didn't define it with an <appender> tag, you can't reference it. Game over.

The Exploit: From XML to RCE

Let's construct an attack. We are assuming you have achieved file write access—maybe via a directory traversal bug in a different service, or perhaps you're an insider threat with access to the deployment repo.

Target: An application utilizing logback-core < 1.5.25. Goal: Execute code during application startup/reload.

First, we need a Gadget. Since this isn't a deserialization bug, we don't need a complex chain like CommonsCollections. We just need a class that does something interesting in its Constructor or Static Initializer.

Let's assume the classpath contains a utility class with a static block that registers a service or performs a lookup.

The Malicious logback.xml:

<configuration>
  <!-- Standard Setup -->
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder><pattern>%msg%n</pattern></encoder>
  </appender>
 
  <root level="debug">
    <!-- Valid reference -->
    <appender-ref ref="STDOUT" />
    
    <!-- THE TRIGGER -->
    <!-- Joran looks for appender named 'com.evil.Gadget'. Fails. -->
    <!-- Joran tries Class.forName('com.evil.Gadget').newInstance() -->
    <appender-ref ref="com.evil.Gadget" />
  </root>
</configuration>

When the application restarts or reloads the configuration (Logback supports scan="true" for hot-reloading!), Joran parses the tree. It hits the malicious ref. It fails to find the appender. It falls back to reflection. The class com.evil.Gadget is instantiated.

If com.evil.Gadget puts a shell connection in its constructor, you now have a shell running as the application user.

The Impact: Why Panic Over a 1.8 CVSS?

You might look at the CVSS score of 1.8 and laugh. 'Low severity? Why are we even talking about this?'

Context is king. The score is low because the Attack Vector is local (AV:L) and requires high privileges (PR:H - write access to config). But in the real world, vulnerabilities are rarely exploited in isolation. They are chained.

Imagine a scenario where you have a limited Arbitrary File Write (AFW) vulnerability. Usually, turning a file write into Code Execution (RCE) requires overwriting a binary, a web shell in a specific directory, or a cron job—all of which might be blocked by OS permissions or read-only filesystems.

However, logback.xml is often writable by the application user to allow for log level adjustments. This CVE turns a simple text file modification into full code execution. It is a persistence gadget and a privilege escalation helper.

If an attacker is on your box and modifies your logging config, they aren't just messing with your audit trails; they are embedding a logic bomb that detonates the next time your app restarts.

The Fix: Remediation

The remediation is straightforward: Update to Logback-core 1.5.25.

If you cannot update immediately, you must treat your configuration files as executable code.

  1. Lock down permissions: Ensure logback.xml is read-only for the application user.
  2. Disable Scanning: If you use <configuration scan="true">, turn it off. Hot-reloading configs gives an attacker an instant trigger mechanism.
  3. Monitor Logs: This patch adds a specific warning: Appender named [...] could not be found. If you see this in your logs, especially referencing strange class names, investigate immediately.

Don't let your logging library be the reason you get paged at 3 AM.

Official Patches

QOS.CHOfficial Release Notes for 1.5.25

Fix Analysis (1)

Technical Appendix

CVSS Score
1.8/ 10
CVSS:4.0/AV:L/AC:H/AT:P/PR:H/UI:N/VC:L/VI:L/VA:L/SC:L/SI:L/SA:L/S:N/AU:N/RE:M/U:Green
EPSS Probability
0.03%
Top 93% most exploited

Affected Systems

Java applications using Logback-core for loggingSpring Boot applications (default logging implementation)Systems using Joran configuration engine

Affected Versions Detail

Product
Affected Versions
Fixed Version
Logback-core
QOS.CH
< 1.5.251.5.25
AttributeDetail
CWE IDCWE-470
Attack VectorLocal (File Write)
CVSS v4.01.8 (Low)
ImpactArbitrary Code Execution
Privileges RequiredHigh (Write Access)
Exploit StatusPoc / Theoretical

MITRE ATT&CK Mapping

T1546Event Triggered Execution
Persistence
T1068Exploitation for Privilege Escalation
Privilege Escalation
T1574Hijack Execution Flow
Persistence
CWE-470
Unsafe Reflection

Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection')

Known Exploits & Detection

Internal ResearchTheoretical exploitation via local configuration modification

Vulnerability Timeline

Patch committed by maintainer
2026-01-15
Logback 1.5.25 released
2026-01-17
CVE Published
2026-01-22

References & Sources

  • [1]GitHub Advisory: Arbitrary Code Execution in Logback
  • [2]Logback News & Release History
Related Vulnerabilities
CVE-2021-44228CVE-2025-11226

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•29 minutes ago•CVE-2026-49866
7.5

CVE-2026-49866: CPU-Based Denial of Service in @libp2p/gossipsub Protobuf Parser

A high-severity denial-of-service vulnerability in @libp2p/gossipsub prior to version 16.0.0 allows unauthenticated remote attackers to trigger event loop starvation and complete node freeze by exploiting unbounded protobuf decoding limits and nested synchronous array iteration loops.

Amit Schendel
Amit Schendel
1 views•6 min read
•about 1 hour ago•CVE-2026-49858
5.9

CVE-2026-49858: Cross-User Attribute and Relation Leak in API Platform Core Serializers

CVE-2026-49858 is a vulnerability in API Platform Core's JSON:API and HAL item normalizers where conditionally secured attributes are cached globally in memory. When deployed in long-running PHP execution environments such as FrankenPHP worker mode, Swoole, or RoadRunner, this persistent caching bypasses property-level security constraints, allowing unprivileged users to access sensitive, unauthorized fields cached during privileged requests.

Alon Barad
Alon Barad
4 views•7 min read
•about 2 hours ago•CVE-2026-5078
5.3

CVE-2026-5078: Log Forging and Injection via :remote-user Token in Morgan Logging Middleware

CVE-2026-5078 is a log injection vulnerability in Morgan, the widely deployed Node.js HTTP request logging middleware. The vulnerability arises because the ':remote-user' logging token decodes and outputs basic authentication usernames containing control characters, such as Carriage Return (CR) and Line Feed (LF), without sanitization. An unauthenticated attacker can bypass native HTTP header parsers by Base64-encoding CRLF sequences in the Authorization header. When Morgan logs the request, these control characters force newlines in the log stream, enabling log forging, SIEM evasion, and system activity spoofing.

Alon Barad
Alon Barad
3 views•7 min read
•about 13 hours ago•CVE-2026-48861
2.1

CVE-2026-48861: HTTP Request Splitting and Smuggling via Method Parameter CRLF Injection in Elixir Mint

CVE-2026-48861 is a client-side HTTP request-line CRLF (Carriage Return Line Feed) injection vulnerability in the popular Elixir HTTP client library, Mint. The vulnerability permits HTTP Request Splitting and HTTP Request Smuggling when an application forwards untrusted, attacker-controlled inputs to Mint's HTTP client requests as either the HTTP request method or target. By embedding CRLF characters within these parameters, an attacker can terminate the request line prematurely, inject malicious headers, or pipeline entirely independent requests. These smuggled requests are then processed by upstream or downstream proxy servers as separate HTTP queries on the same TCP connection. While Mint version 1.7.0 introduced target validation to secure the request target, the HTTP request method parameter remained completely unvalidated. This flaw allows attackers to bypass routing filters, access restricted internal APIs, or poison HTTP caches under default configurations.

Amit Schendel
Amit Schendel
6 views•7 min read
•about 13 hours ago•CVE-2026-49753
6.3

CVE-2026-49753: HTTP Request/Response Smuggling via Inconsistent Content-Length Parsing in Elixir Mint Client

An Inconsistent Interpretation of HTTP Requests (HTTP Request/Response Smuggling) vulnerability in the Elixir Mint HTTP client allows attacker-controlled HTTP/1 servers to desynchronize response framing on shared connections due to over-lenient parsing of sign-prefixed Content-Length headers.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 14 hours ago•CVE-2026-49754
8.2

CVE-2026-49754: Denial of Service via Unbounded HTTP/2 CONTINUATION Frame Accumulation in Elixir Mint

An allocation of resources without limits or throttling vulnerability in Elixir Mint allows an attacker-controlled HTTP/2 server to exhaust memory in a Mint client. The vulnerability is exploited by sending a HEADERS frame without the END_HEADERS flag followed by an infinite stream of CONTINUATION frames. Because the client lacks limits on the incoming header-block accumulator, the client continuously consumes memory until an out-of-memory crash occurs.

Amit Schendel
Amit Schendel
7 views•6 min read