Projects
home:Eustace:branches:Eulaceura:Factory
log4j12
_service:obs_scm:CVE-2022-23307.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:CVE-2022-23307.patch of Package log4j12
From: Markus Koschany <apo@debian.org> Date: Mon, 31 Jan 2022 11:37:03 +0100 Subject: CVE-2022-23307 Origin: https://github.com/qos-ch/reload4j/commit/64902fe18ce5a5dd40487051a2f6231d9fbbe9b0 --- .../org/apache/log4j/chainsaw/LoggingReceiver.java | 8 +- .../log4j/net/HardenedLoggingEventInputStream.java | 56 +++++++++++++ .../log4j/net/HardenedObjectInputStream.java | 93 +++++++++++++++++++++ src/test/input/xml/socketAppenderForChainsaw.xml | 24 ++++++ .../org/apache/log4j/net/SocketAppenderTest.java | 96 ++++++++++++++++++++++ 5 files changed, 273 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/apache/log4j/net/HardenedLoggingEventInputStream.java create mode 100644 src/main/java/org/apache/log4j/net/HardenedObjectInputStream.java create mode 100644 src/test/input/xml/socketAppenderForChainsaw.xml create mode 100644 src/test/java/org/apache/log4j/net/SocketAppenderTest.java diff --git a/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java b/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java index ca087ad..74ecc06 100644 --- a/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java +++ b/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java @@ -18,11 +18,11 @@ package org.apache.log4j.chainsaw; import java.io.EOFException; import java.io.IOException; -import java.io.ObjectInputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import org.apache.log4j.Logger; +import org.apache.log4j.net.HardenedLoggingEventInputStream; import org.apache.log4j.spi.LoggingEvent; /** @@ -58,10 +58,10 @@ class LoggingReceiver extends Thread { public void run() { LOG.debug("Starting to get data"); try { - final ObjectInputStream ois = - new ObjectInputStream(mClient.getInputStream()); + final HardenedLoggingEventInputStream hleis = + new HardenedLoggingEventInputStream(mClient.getInputStream()); while (true) { - final LoggingEvent event = (LoggingEvent) ois.readObject(); + final LoggingEvent event = (LoggingEvent) hleis.readObject(); mModel.addEvent(new EventDetails(event)); } } catch (EOFException e) { diff --git a/src/main/java/org/apache/log4j/net/HardenedLoggingEventInputStream.java b/src/main/java/org/apache/log4j/net/HardenedLoggingEventInputStream.java new file mode 100644 index 0000000..f0f6a20 --- /dev/null +++ b/src/main/java/org/apache/log4j/net/HardenedLoggingEventInputStream.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.net; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Level; +import org.apache.log4j.Priority; +import org.apache.log4j.spi.LocationInfo; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.spi.ThrowableInformation; + +// === Copied from the logback project with permission == +public class HardenedLoggingEventInputStream extends HardenedObjectInputStream { + + static final String ARRAY_PREFIX = "[L"; + + static public List<String> getWhilelist() { + + List<String> whitelist = new ArrayList<String>(); + whitelist.add(LoggingEvent.class.getName()); + whitelist.add(Level.class.getName()); + whitelist.add(Priority.class.getName()); + whitelist.add(ThrowableInformation.class.getName()); + whitelist.add(LocationInfo.class.getName()); + + return whitelist; + } + + public HardenedLoggingEventInputStream(InputStream is) throws IOException { + super(is, getWhilelist()); + } + + public HardenedLoggingEventInputStream(InputStream is, List<String> additionalAuthorizedClasses) + throws IOException { + this(is); + super.addToWhitelist(additionalAuthorizedClasses); + } +} diff --git a/src/main/java/org/apache/log4j/net/HardenedObjectInputStream.java b/src/main/java/org/apache/log4j/net/HardenedObjectInputStream.java new file mode 100644 index 0000000..c911572 --- /dev/null +++ b/src/main/java/org/apache/log4j/net/HardenedObjectInputStream.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.net; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; +import java.util.ArrayList; +import java.util.List; + +/** + * HardenedObjectInputStream restricts the set of classes that can be + * deserialized to a set of explicitly whitelisted classes. This prevents + * certain type of attacks from being successful. + * + * <p> + * It is assumed that classes in the "java.lang" and "java.util" packages are + * always authorized. + * </p> + * + * @author Ceki Gülcü + * @since 1.2.18 + * + * === Copied from the logback project with permission == + */ +public class HardenedObjectInputStream extends ObjectInputStream { + + static final String ARRAY_CLASS_PREFIX = "[L"; + final List<String> whitelistedClassNames; + final static String[] JAVA_PACKAGES = new String[] { "java.lang", "java.util", ARRAY_CLASS_PREFIX + "java.lang" }; + + public HardenedObjectInputStream(InputStream in, String[] whilelist) throws IOException { + super(in); + + this.whitelistedClassNames = new ArrayList<String>(); + if (whilelist != null) { + for (int i = 0; i < whilelist.length; i++) { + this.whitelistedClassNames.add(whilelist[i]); + } + } + } + + public HardenedObjectInputStream(InputStream in, List<String> whitelist) throws IOException { + super(in); + + this.whitelistedClassNames = new ArrayList<String>(); + this.whitelistedClassNames.addAll(whitelist); + } + + @Override + protected Class<?> resolveClass(ObjectStreamClass anObjectStreamClass) throws IOException, ClassNotFoundException { + + String incomingClassName = anObjectStreamClass.getName(); + + if (!isWhitelisted(incomingClassName)) { + throw new InvalidClassException("Unauthorized deserialization attempt", incomingClassName); + } + + return super.resolveClass(anObjectStreamClass); + } + + private boolean isWhitelisted(String incomingClassName) { + for (int i = 0; i < JAVA_PACKAGES.length; i++) { + if (incomingClassName.startsWith(JAVA_PACKAGES[i])) + return true; + } + for (String whiteListed : whitelistedClassNames) { + if (incomingClassName.equals(whiteListed)) + return true; + } + return false; + } + + protected void addToWhitelist(List<String> additionalAuthorizedClasses) { + whitelistedClassNames.addAll(additionalAuthorizedClasses); + } +} \ No newline at end of file diff --git a/src/test/input/xml/socketAppenderForChainsaw.xml b/src/test/input/xml/socketAppenderForChainsaw.xml new file mode 100644 index 0000000..b022ba5 --- /dev/null +++ b/src/test/input/xml/socketAppenderForChainsaw.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration debug="true" +xmlns:log4j='http://jakarta.apache.org/log4j/'> + + + <!-- primary appender --> + <appender name="REMOTE" class="org.apache.log4j.net.SocketAppender"> + + <param name="RemoteHost" value="localhost"/> + <param name="Port" value="4445"/> + <param name="ReconnectionDelay" value="10"/> + </appender> + + <root> + <priority value ="trace" /> + <appender-ref ref="REMOTE" /> + </root> + + +</log4j:configuration> + + diff --git a/src/test/java/org/apache/log4j/net/SocketAppenderTest.java b/src/test/java/org/apache/log4j/net/SocketAppenderTest.java new file mode 100644 index 0000000..6c4a390 --- /dev/null +++ b/src/test/java/org/apache/log4j/net/SocketAppenderTest.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.net; + +import static org.apache.log4j.TestContants.TEST_INPUT_PREFIX; +import static org.junit.Assert.assertEquals; + +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.Logger; +import org.apache.log4j.spi.LoggingEvent; +import org.apache.log4j.xml.DOMConfigurator; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class SocketAppenderTest { + + /* JUnit's setUp and tearDown */ + + @Before + public void setUp() { + DOMConfigurator.configure(TEST_INPUT_PREFIX + "xml/SocketAppenderTestConfig.xml"); + // DOMConfigurator.configure(TEST_INPUT_PREFIX + + // "xml/socketAppenderForChainsaw.xml"); + + logger = Logger.getLogger(SocketAppenderTest.class); + secondary = (LastOnlyAppender) Logger.getLogger("org.apache.log4j.net.SocketAppenderTestDummy") + .getAppender("lastOnly"); + } + + @After + public void tearDown() { + } + + /* Tests */ + + @Test + public void testFallbackErrorHandlerWhenStarting() { + String msg = "testFallbackErrorHandlerWhenStarting"; + logger.debug(msg); + + // above debug log will fail and shoul be redirected to secondary appender + assertEquals("SocketAppender with FallbackErrorHandler", msg, secondary.getLastMessage()); + } + + /* Fields */ + + private static Logger logger; + private static LastOnlyAppender secondary; + + /* Inner classes */ + + /** + * Inner-class For debugging purposes only Saves last LoggerEvent + */ + static public class LastOnlyAppender extends AppenderSkeleton { + protected void append(LoggingEvent event) { + this.lastEvent = event; + } + + public boolean requiresLayout() { + return false; + } + + public void close() { + this.closed = true; + } + + /** + * @return last appended LoggingEvent's message + */ + public String getLastMessage() { + if (this.lastEvent != null) + return this.lastEvent.getMessage().toString(); + else + return ""; + } + + private LoggingEvent lastEvent; + }; + +} \ No newline at end of file
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2