1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
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 <stephen.webb@ieee.org>
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(-)
diff --git a/src/main/cpp/jsonlayout.cpp b/src/main/cpp/jsonlayout.cpp
index d8d062d79..3e0abf486 100644
--- a/src/main/cpp/jsonlayout.cpp
+++ b/src/main/cpp/jsonlayout.cpp
@@ -215,32 +215,31 @@ void JSONLayout::appendQuotedEscapedString(LogString& buf,
void JSONLayout::appendItem(const LogString& input, LogString& buf)
{
- /* 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 */
@@ -285,20 +284,15 @@ void JSONLayout::appendItem(const LogString& input, LogString& buf)
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())
diff --git a/src/test/cpp/jsonlayouttest.cpp b/src/test/cpp/jsonlayouttest.cpp
index fda39fca2..75f17dc0a 100644
--- a/src/test/cpp/jsonlayouttest.cpp
+++ b/src/test/cpp/jsonlayouttest.cpp
@@ -163,6 +163,20 @@ LOGUNIT_CLASS(JSONLayoutTest), public JSONLayout
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);
}
/**
|