This is an automated email from the ASF dual-hosted git repository. joerghoh pushed a commit to branch SLING-13360 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-engine.git
commit 77d4499f718c3c2d39cd3ad7da2bf859a3bcdc70 Author: Joerg Hoh <[email protected]> AuthorDate: Tue Sep 22 13:38:08 2026 +0200 SLING-13360 all log directives should handle CR/LF escaping --- .../sling/engine/impl/log/CustomLogFormat.java | 11 +++--- .../sling/engine/impl/log/CustomLogFormatTest.java | 40 ++++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/sling/engine/impl/log/CustomLogFormat.java b/src/main/java/org/apache/sling/engine/impl/log/CustomLogFormat.java index 8d353b5..e67b119 100644 --- a/src/main/java/org/apache/sling/engine/impl/log/CustomLogFormat.java +++ b/src/main/java/org/apache/sling/engine/impl/log/CustomLogFormat.java @@ -547,7 +547,7 @@ class CustomLogFormat { } protected String getValue(RequestLoggerRequest request) { - return Thread.currentThread().getName(); + return escape(Thread.currentThread().getName()); } protected String getValue(RequestLoggerResponse response) { @@ -561,7 +561,7 @@ class CustomLogFormat { } protected String getValue(RequestLoggerRequest request) { - return request.getParameter(this.getParParam()); + return escape(request.getParameter(this.getParParam())); } protected String getValue(RequestLoggerResponse response) { @@ -705,7 +705,7 @@ class CustomLogFormat { } protected String getValue(RequestLoggerRequest request) { - return request.getRemoteHost(); + return escape(request.getRemoteHost()); } protected String getValue(RequestLoggerResponse response) { @@ -763,7 +763,10 @@ class CustomLogFormat { protected String getValue(RequestLoggerRequest request) { final Object resourcePath = request.getAttribute(RequestData.REQUEST_RESOURCE_PATH_ATTR); if (resourcePath instanceof String) { - return (String) resourcePath; + // the resolved resource path is derived from the decoded request + // path and may contain control characters (e.g. for non-existing + // resources), so it must be escaped like other request data + return escape((String) resourcePath); } return null; } diff --git a/src/test/java/org/apache/sling/engine/impl/log/CustomLogFormatTest.java b/src/test/java/org/apache/sling/engine/impl/log/CustomLogFormatTest.java index 1553e88..9738cae 100644 --- a/src/test/java/org/apache/sling/engine/impl/log/CustomLogFormatTest.java +++ b/src/test/java/org/apache/sling/engine/impl/log/CustomLogFormatTest.java @@ -19,6 +19,8 @@ package org.apache.sling.engine.impl.log; import junit.framework.TestCase; +import org.apache.sling.engine.impl.request.RequestData; +import org.mockito.Mockito; /** * The <code>CustomLogFormatTest</code> class tests the @@ -69,4 +71,42 @@ public class CustomLogFormatTest extends TestCase { "This is a special character \\u1234", CustomLogFormat.HeaderParameter.escape("This is a special character \u1234")); } + + public void testRequestParameterValueEscaped() { + final RequestLoggerRequest request = Mockito.mock(RequestLoggerRequest.class); + Mockito.when(request.getParameter("ref")) + .thenReturn("x\r\n192.168.1.1 - admin \"POST /system/console HTTP/1.1\" 200"); + + final CustomLogFormat.ParamParameter param = new CustomLogFormat.ParamParameter("ref"); + final String value = param.getValue(request); + + // no raw CR/LF may end up in the log line + assertFalse(value.contains("\r")); + assertFalse(value.contains("\n")); + assertEquals("x\\r\\n192.168.1.1 - admin \\\"POST /system/console HTTP/1.1\\\" 200", value); + } + + public void testContentPathEscaped() { + final RequestLoggerRequest request = Mockito.mock(RequestLoggerRequest.class); + Mockito.when(request.getAttribute(RequestData.REQUEST_RESOURCE_PATH_ATTR)) + .thenReturn("/content/foo\r\nFORGED LINE"); + + final CustomLogFormat.ContentPathParameter param = new CustomLogFormat.ContentPathParameter(); + final String value = param.getValue(request); + + assertFalse(value.contains("\r")); + assertFalse(value.contains("\n")); + assertEquals("/content/foo\\r\\nFORGED LINE", value); + } + + public void testRemoteHostEscaped() { + final RequestLoggerRequest request = Mockito.mock(RequestLoggerRequest.class); + Mockito.when(request.getRemoteHost()).thenReturn("evil\nhost.example.com"); + + final CustomLogFormat.RemoteHostParameter param = new CustomLogFormat.RemoteHostParameter(); + final String value = param.getValue(request); + + assertFalse(value.contains("\n")); + assertEquals("evil\\nhost.example.com", value); + } }
