Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: [email protected], [email protected]
Control: affects -1 + src:log4cxx
User: [email protected]
Usertags: pu
These are the same fixes as already seen for the trixie-pu
log4cxx/1.4.0-1+deb13u1, #1120278.
This SPU is now filling the gap between LTS and stable, so that an
update from bullseye to bookworm won't lead to regressions.
(I'm confident that this update will be accepted, therefore I'll uploaded
the package already.)
[ Reason ]
For log4cxx those vulnerabilities have been reported:
CVE-2025-54812 and CVE-2025-54813, both are improper sanitatation
vulnerabilities (quoted from DLA-4322-1):
CVE-2025-54812
When using HTMLLayout, logger names are not properly escaped when
writing out to the HTML file. If untrusted data is used to retrieve
the name of a logger, an attacker could theoretically inject HTML or
Javascript in order to hide information from logs or steal data from
the user.
CVE-2025-54813
When using JSONLayout, not all payload bytes are properly escaped.
If an attacker-supplied message contains certain non-printable
characters, these will be passed along in the message and written out
as part of the JSON message. This may prevent applications that
consume these logs from correctly interpreting the information within
them.
[ Impact ]
Regression when updating from older Debian releaeses.
[ Tests ]
There are upstream unit tests for the CVEs.
[ Risks ]
The patches are cherry-picked from upstream and applied cleanly without
modifications (the affected code paths have not changed much since the
version in bookworm.) The patches are also not very complex. And, due
to the tests, I think the risk of regressions is quite low.
[ Checklist ]
[X] *all* changes are documented in the d/changelog
[X] I reviewed all changes and I approve them
[X] attach debdiff against the package in (old)stable
--
tobi
diff -Nru log4cxx-1.0.0/debian/changelog log4cxx-1.0.0/debian/changelog
--- log4cxx-1.0.0/debian/changelog 2023-01-09 02:30:15.000000000 +0100
+++ log4cxx-1.0.0/debian/changelog 2025-12-07 10:34:47.000000000 +0100
@@ -1,3 +1,12 @@
+log4cxx (1.0.0-1+deb12u1) bookworm; urgency=medium
+
+ [ Lukas Märdian and Tobias Frost ]
+ * Backport fixes for:
+ - CVE-2025-54812: Improper HTML escaping in HTMLLayout (Closes: #1111879)
+ - CVE-2025-54813: Improper escaping with JSONLayout (Closes: #1111881)
+
+ -- Tobias Frost <[email protected]> Sun, 07 Dec 2025 10:34:47 +0100
+
log4cxx (1.0.0-1) unstable; urgency=medium
* New upstream release.
diff -Nru log4cxx-1.0.0/debian/gbp.conf log4cxx-1.0.0/debian/gbp.conf
--- log4cxx-1.0.0/debian/gbp.conf 2023-01-09 02:26:30.000000000 +0100
+++ log4cxx-1.0.0/debian/gbp.conf 2025-12-07 10:12:05.000000000 +0100
@@ -1,5 +1,5 @@
[DEFAULT]
upstream-branch=upstream
-debian-branch=master
+debian-branch=debian/bookworm
pristine-tar = True
sign-tags = True
diff -Nru
log4cxx-1.0.0/debian/patches/04-CVE-2025-54812-1-Escape-loggername.patch
log4cxx-1.0.0/debian/patches/04-CVE-2025-54812-1-Escape-loggername.patch
--- log4cxx-1.0.0/debian/patches/04-CVE-2025-54812-1-Escape-loggername.patch
1970-01-01 01:00:00.000000000 +0100
+++ log4cxx-1.0.0/debian/patches/04-CVE-2025-54812-1-Escape-loggername.patch
2025-12-07 10:11:55.000000000 +0100
@@ -0,0 +1,131 @@
+Description: CVE-2025-54812 - part 1 - Improper HTML escaping in HTMLLayout
+Origin:
https://github.com/apache/logging-log4cxx/commit/1c599de956ae9eedd8b5e3f744bfb867c39e8bba
+Bug: https://logging.apache.org/security.html#CVE-2025-54812
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1111879
+
+From 1c599de956ae9eedd8b5e3f744bfb867c39e8bba Mon Sep 17 00:00:00 2001
+From: Stephen Webb <[email protected]>
+Date: Sat, 12 Jul 2025 10:19:03 +1000
+Subject: [PATCH] Escape any logger name '&' or '"' in html attribute data
+ (#509)
+
+---
+ src/main/cpp/htmllayout.cpp | 8 ++---
+ src/test/cpp/xml/xmllayouttest.cpp | 49 ++++++++++++++++++++++++++++++
+ 2 files changed, 53 insertions(+), 4 deletions(-)
+
+diff --git a/src/main/cpp/htmllayout.cpp b/src/main/cpp/htmllayout.cpp
+index c2411ece9..ed6e61d76 100644
+--- a/src/main/cpp/htmllayout.cpp
++++ b/src/main/cpp/htmllayout.cpp
+@@ -109,25 +109,25 @@ void HTMLLayout::format(LogString& output,
+ if (event->getLevel()->equals(Level::getDebug()))
+ {
+ output.append(LOG4CXX_STR("<font color=\"#339933\">"));
+- output.append(event->getLevel()->toString());
++ Transform::appendEscapingTags(output,
event->getLevel()->toString());
+ output.append(LOG4CXX_STR("</font>"));
+ }
+ else if (event->getLevel()->isGreaterOrEqual(Level::getWarn()))
+ {
+ output.append(LOG4CXX_STR("<font color=\"#993300\"><strong>"));
+- output.append(event->getLevel()->toString());
++ Transform::appendEscapingTags(output,
event->getLevel()->toString());
+ output.append(LOG4CXX_STR("</strong></font>"));
+ }
+ else
+ {
+- output.append(event->getLevel()->toString());
++ Transform::appendEscapingTags(output,
event->getLevel()->toString());
+ }
+
+ output.append(LOG4CXX_STR("</td>"));
+ output.append(LOG4CXX_EOL);
+
+ output.append(LOG4CXX_STR("<td title=\""));
+- output.append(event->getLoggerName());
++ Transform::appendEscapingTags(output, event->getLoggerName());
+ output.append(LOG4CXX_STR(" logger\">"));
+ Transform::appendEscapingTags(output, event->getLoggerName());
+ output.append(LOG4CXX_STR("</td>"));
+diff --git a/src/test/cpp/xml/xmllayouttest.cpp
b/src/test/cpp/xml/xmllayouttest.cpp
+index 78f1c1183..710e9fca4 100644
+--- a/src/test/cpp/xml/xmllayouttest.cpp
++++ b/src/test/cpp/xml/xmllayouttest.cpp
+@@ -18,6 +18,7 @@
+ #include "../logunit.h"
+ #include <log4cxx/logger.h>
+ #include <log4cxx/xml/xmllayout.h>
++#include <log4cxx/htmllayout.h>
+ #include <log4cxx/fileappender.h>
+ #include <log4cxx/mdc.h>
+
+@@ -37,6 +38,7 @@
+ #include "../xml/xlevel.h"
+ #include <log4cxx/helpers/bytebuffer.h>
+ #include <log4cxx/helpers/transcoder.h>
++#include <log4cxx/helpers/loglog.h>
+
+
+ using namespace log4cxx;
+@@ -67,6 +69,7 @@ LOGUNIT_CLASS(XMLLayoutTest)
+ LOGUNIT_TEST(testActivateOptions);
+ LOGUNIT_TEST(testProblemCharacters);
+ LOGUNIT_TEST(testNDCWithCDATA);
++ LOGUNIT_TEST(testHTMLLayout);
+ LOGUNIT_TEST_SUITE_END();
+
+
+@@ -453,6 +456,52 @@ LOGUNIT_CLASS(XMLLayoutTest)
+ LOGUNIT_ASSERT_EQUAL(1, ndcCount);
+ }
+
++ /**
++ * Tests problematic characters in multiple fields.
++ * @throws Exception if parser can not be constructed or source is not
a valid XML document.
++ */
++ void testHTMLLayout()
++ {
++ LogString problemName = LOG4CXX_STR("com.example.bar<>&\"'");
++ auto level = std::make_shared<XLevel>(6000, problemName, 7);
++ NDC context(problemName);
++ auto event = std::make_shared<LoggingEvent>(problemName, level,
problemName, LOG4CXX_LOCATION);
++
++ HTMLLayout layout;
++ Pool p;
++ LogString html(LOG4CXX_STR("<body>"));
++ layout.format(html, event, p);
++ html += LOG4CXX_STR("</body>");
++
++ LogLog::debug(html);
++ char backing[3000];
++ ByteBuffer buf(backing, sizeof(backing));
++ CharsetEncoderPtr encoder(CharsetEncoder::getUTF8Encoder());
++ LogString::const_iterator iter{ html.begin() };
++ encoder->encode(html, iter, buf);
++ LOGUNIT_ASSERT(iter == html.end());
++ buf.flip();
++ auto parser = apr_xml_parser_create(p.getAPRPool());
++ LOGUNIT_ASSERT(parser != 0);
++ auto stat = apr_xml_parser_feed(parser, buf.data(),
buf.remaining());
++ LOGUNIT_ASSERT(stat == APR_SUCCESS);
++ apr_xml_doc* doc = 0;
++ stat = apr_xml_parser_done(parser, &doc);
++ LOGUNIT_ASSERT(doc != 0);
++ auto parsedResult = doc->root;
++ LOGUNIT_ASSERT(parsedResult != 0);
++
++ int childElementCount = 0;
++ for ( auto node = parsedResult->first_child
++ ; node != NULL
++ ; node = node->next)
++ {
++ ++childElementCount;
++ LOGUNIT_ASSERT_EQUAL(std::string("tr"),
std::string(node->name));
++ }
++ LOGUNIT_ASSERT(1 < childElementCount);
++ }
++
+ };
+
+
diff -Nru
log4cxx-1.0.0/debian/patches/05-CVE-2025-54812-2-Escape-threadname.patch
log4cxx-1.0.0/debian/patches/05-CVE-2025-54812-2-Escape-threadname.patch
--- log4cxx-1.0.0/debian/patches/05-CVE-2025-54812-2-Escape-threadname.patch
1970-01-01 01:00:00.000000000 +0100
+++ log4cxx-1.0.0/debian/patches/05-CVE-2025-54812-2-Escape-threadname.patch
2025-12-07 10:11:55.000000000 +0100
@@ -0,0 +1,30 @@
+Description: CVE-2025-54812 - part 2 - Improper escaping in html attribute data
+Origin: https://github.com/apache/logging-log4cxx/pull/509
+Bug: https://logging.apache.org/security.html#CVE-2025-54812
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1111879
+
+From 0b3749504f0f1bd83ca8a7b391687fdfcd1f94a6 Mon Sep 17 00:00:00 2001
+From: Stephen Webb <[email protected]>
+Date: Thu, 24 Jul 2025 11:18:34 +1000
+Subject: [PATCH] Escape any logger name '&' or '"' in html attribute data
+
+---
+ src/main/cpp/htmllayout.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/main/cpp/htmllayout.cpp b/src/main/cpp/htmllayout.cpp
+index cce9c1dc2..f1b2747c4 100644
+--- a/src/main/cpp/htmllayout.cpp
++++ b/src/main/cpp/htmllayout.cpp
+@@ -98,9 +98,9 @@ void HTMLLayout::format(LogString& output,
+
+ output.append(LOG4CXX_STR("<td title=\""));
+ LogString threadName(event->getThreadName());
+- output.append(threadName);
++ Transform::appendEscapingTags(output, threadName);
+ output.append(LOG4CXX_STR(" thread\">"));
+- output.append(threadName);
++ Transform::appendEscapingTags(output, threadName);
+ output.append(LOG4CXX_STR("</td>"));
+ output.append(LOG4CXX_EOL);
+
diff -Nru
log4cxx-1.0.0/debian/patches/06-CVE-2025-54812-3-Escape-html-layout-title.patch
log4cxx-1.0.0/debian/patches/06-CVE-2025-54812-3-Escape-html-layout-title.patch
---
log4cxx-1.0.0/debian/patches/06-CVE-2025-54812-3-Escape-html-layout-title.patch
1970-01-01 01:00:00.000000000 +0100
+++
log4cxx-1.0.0/debian/patches/06-CVE-2025-54812-3-Escape-html-layout-title.patch
2025-12-07 10:11:55.000000000 +0100
@@ -0,0 +1,28 @@
+Description: CVE-2025-54812 - part 3 - inproper escape of thread name in
htmllayoutappender
+Origin: https://github.com/apache/logging-log4cxx/pull/513
+Bug: https://logging.apache.org/security.html#CVE-2025-54812
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1111879
+
+From ffc2ab7138577bca0e4f0b0d48cacd386cce09cd Mon Sep 17 00:00:00 2001
+From: Stephen Webb <[email protected]>
+Date: Mon, 21 Jul 2025 15:43:01 +1000
+Subject: [PATCH] Allow a HTMLLayout title to contain characters special to
+ HTML
+
+---
+ src/main/cpp/htmllayout.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/main/cpp/htmllayout.cpp b/src/main/cpp/htmllayout.cpp
+index ed6e61d76..cce9c1dc2 100644
+--- a/src/main/cpp/htmllayout.cpp
++++ b/src/main/cpp/htmllayout.cpp
+@@ -183,7 +183,7 @@ void HTMLLayout::appendHeader(LogString& output, Pool& p)
+ output.append(LOG4CXX_STR("<head>"));
+ output.append(LOG4CXX_EOL);
+ output.append(LOG4CXX_STR("<title>"));
+- output.append(m_priv->title);
++ Transform::appendEscapingTags(output, m_priv->title);
+ output.append(LOG4CXX_STR("</title>"));
+ output.append(LOG4CXX_EOL);
+ output.append(LOG4CXX_STR("<style type=\"text/css\">"));
diff -Nru
log4cxx-1.0.0/debian/patches/07-CVE-2025-54813-Escape-control-characters-in-JSONLayout.patch
log4cxx-1.0.0/debian/patches/07-CVE-2025-54813-Escape-control-characters-in-JSONLayout.patch
---
log4cxx-1.0.0/debian/patches/07-CVE-2025-54813-Escape-control-characters-in-JSONLayout.patch
1970-01-01 01:00:00.000000000 +0100
+++
log4cxx-1.0.0/debian/patches/07-CVE-2025-54813-Escape-control-characters-in-JSONLayout.patch
2025-12-07 10:27:37.000000000 +0100
@@ -0,0 +1,117 @@
+Description: CVE-2025-54813 - Improper escaping with JSONLayout
+Origin:
https://github.com/apache/logging-log4cxx/commit/a799c934545311ff4179c68e16bbeb02b5c66348
+Bug: https://logging.apache.org/security.html#CVE-2025-54813
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1111881
+
+From a799c934545311ff4179c68e16bbeb02b5c66348 Mon Sep 17 00:00:00 2001
+From: Stephen Webb <[email protected]>
+Date: Tue, 22 Jul 2025 11:32:03 +1000
+Subject: [PATCH] Escape control characters in JSONLayout data (#512)
+
+---
+ src/main/cpp/jsonlayout.cpp | 52 +++++++++++++++------------------
+ src/test/cpp/jsonlayouttest.cpp | 14 +++++++++
+ 2 files changed, 37 insertions(+), 29 deletions(-)
+
+--- a/src/main/cpp/jsonlayout.cpp
++++ b/src/main/cpp/jsonlayout.cpp
+@@ -173,32 +173,31 @@
+ void JSONLayout::appendQuotedEscapedString(LogString& buf,
+ const LogString& input) const
+ {
+- /* add leading quote */
+- buf.push_back(0x22);
+-
+- logchar specialChars[] =
++ auto toHexDigit = [](int ch) -> int
+ {
+- 0x08, /* \b backspace */
+- 0x09, /* \t tab */
+- 0x0a, /* \n newline */
+- 0x0c, /* \f form feed */
+- 0x0d, /* \r carriage return */
+- 0x22, /* \" double quote */
+- 0x5c, /* \\ backslash */
+- 0x00 /* terminating NULL for C-strings */
++ return (10 <= ch ? (0x61 - 10) : 0x30) + ch;
+ };
++ /* add leading quote */
++ buf.push_back(0x22);
+
+ size_t start = 0;
+- size_t found = input.find_first_of(specialChars, start);
++ size_t index = 0;
+
+- while (found != LogString::npos)
++ for (int ch : input)
+ {
+- if (found > start)
++ if (0x22 == ch || 0x5c == ch)
++ ;
++ else if (0x20 <= ch)
++ {
++ ++index;
++ continue;
++ }
++ if (start < index)
+ {
+- buf.append(input, start, found - start);
++ buf.append(input, start, index - start);
+ }
+
+- switch (input[found])
++ switch (ch)
+ {
+ case 0x08:
+ /* \b backspace */
+@@ -243,20 +242,15 @@
+ break;
+
+ default:
+- buf.push_back(input[found]);
++ buf.push_back(0x5c);
++ buf.push_back(0x75); // 'u'
++ buf.push_back(toHexDigit((ch & 0xF000) >> 12));
++ buf.push_back(toHexDigit((ch & 0xF00) >> 8));
++ buf.push_back(toHexDigit((ch & 0xF0) >> 4));
++ buf.push_back(toHexDigit(ch & 0xF));
+ break;
+ }
+-
+- start = found + 1;
+-
+- if (found < input.size())
+- {
+- found = input.find_first_of(specialChars, start);
+- }
+- else
+- {
+- found = LogString::npos;
+- }
++ start = ++index;
+ }
+
+ if (start < input.size())
+--- a/src/test/cpp/jsonlayouttest.cpp
++++ b/src/test/cpp/jsonlayouttest.cpp
+@@ -163,6 +163,20 @@
+
+ appendQuotedEscapedString(cr_escaped, cr);
+ LOGUNIT_ASSERT_EQUAL(cr_expected, cr_escaped);
++
++ logchar sub[] = {0x1a, 0x00};
++ logchar sub_expected[] = {0x22, 0x5c, 'u', 0x30, 0x30, 0x31,
0x61, 0x22, 0x00}; /* SUB */
++ LogString sub_escaped;
++
++ appendQuotedEscapedString(sub_escaped, sub);
++ LOGUNIT_ASSERT_EQUAL(sub_expected, sub_escaped);
++
++ logchar esc[] = {0x1e, 0x00};
++ logchar esc_expected[] = {0x22, 0x5c, 'u', 0x30, 0x30, 0x31,
0x65, 0x22, 0x00}; /* ESC */
++ LogString esc_escaped;
++
++ appendQuotedEscapedString(esc_escaped, esc);
++ LOGUNIT_ASSERT_EQUAL(esc_expected, esc_escaped);
+ }
+
+ /**
diff -Nru log4cxx-1.0.0/debian/patches/series
log4cxx-1.0.0/debian/patches/series
--- log4cxx-1.0.0/debian/patches/series 2022-12-31 10:14:10.000000000 +0100
+++ log4cxx-1.0.0/debian/patches/series 2025-12-07 10:32:02.000000000 +0100
@@ -1,2 +1,7 @@
01-disable-inetaddresstestcase.patch
02-disable-flaky-multithreadtest.patch
+
+04-CVE-2025-54812-1-Escape-loggername.patch
+05-CVE-2025-54812-2-Escape-threadname.patch
+06-CVE-2025-54812-3-Escape-html-layout-title.patch
+07-CVE-2025-54813-Escape-control-characters-in-JSONLayout.patch