This is an automated email from the ASF dual-hosted git repository. FreeAndNil pushed a commit to branch Feature/security-audit-hardening in repository https://gitbox.apache.org/repos/asf/logging-log4net.git
commit 6bc3df34ba304ec9db6f7c361bf3c1c7279af2eb Author: Jan Friedrich <[email protected]> AuthorDate: Mon Aug 17 21:54:28 2026 +0200 document that configuration is trusted input Security scans regularly report the configuration paths as cleartext transport, credential exposure, unrestricted type loading and unverified reload. None of them is a vulnerability, so record why, with a link to the threat model, at the places a scan actually flags: - InternalConfigure(ILoggerRepository, Uri) neither restricts the URI scheme nor withholds the process credentials. The endpoint is named by the configuration and is trusted for the same reason an appender destination is; transmitting configuration confidentially is a deployer responsibility. Nothing runs until an operator supplies a URI, either by calling Configure(Uri) or through the log4net.Config appSetting. - ParseAppender instantiates the types the configuration names, and SetParameter reaches non-public members, both by design. - ConfigureAndWatchHandler reloads a replaced file without re-checking its origin; keeping the watched file writable only by the operator is a deployer responsibility. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> --- src/log4net/Config/XmlConfigurator.cs | 18 ++++++++++++++++++ .../Repository/Hierarchy/XmlHierarchyConfigurator.cs | 5 +++++ 2 files changed, 23 insertions(+) diff --git a/src/log4net/Config/XmlConfigurator.cs b/src/log4net/Config/XmlConfigurator.cs index e7ffd2db..ece21ae4 100644 --- a/src/log4net/Config/XmlConfigurator.cs +++ b/src/log4net/Config/XmlConfigurator.cs @@ -491,6 +491,20 @@ private static void InternalConfigure(ILoggerRepository repository, Uri? configU } else { + // The URI is not restricted to a particular scheme and the request below is sent with the + // process credentials. Both are intentional and are not vulnerabilities: + // + // Configuration is operator-supplied and therefore trusted, and the endpoint named here is + // part of that configuration - it is trusted for the same reason an appender destination + // is. Ensuring that configuration is transmitted only over a confidential channel, and + // that the endpoint is one the credentials may be presented to, is a deployer + // responsibility. Nothing here is reachable until an operator supplies a URI, either by + // calling Configure(Uri) or through the log4net.Config appSetting. + // + // See the Apache Logging Services common threat model, sections "Configuration + // (operator-controlled)" and "Adversary capabilities": + // https://raw.githubusercontent.com/apache/logging-site/refs/heads/main/src/site/antora/modules/ROOT/pages/_threat-model-common.adoc + // NETCF dose not support WebClient WebRequest? configRequest = null; @@ -749,6 +763,10 @@ private static void InternalConfigureAndWatch(ILoggerRepository repository, File /// </remarks> private sealed class ConfigureAndWatchHandler : IDisposable { + // The replaced file is reloaded without re-checking its origin. Keeping the watched file + // writable only by the operator is a deployer responsibility, see + // https://raw.githubusercontent.com/apache/logging-site/refs/heads/main/src/site/antora/modules/ROOT/pages/_threat-model-common.adoc + /// <summary> /// Holds the FileInfo used to configure the XmlConfigurator /// </summary> diff --git a/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs b/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs index c65b719b..32df0c2d 100644 --- a/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs +++ b/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs @@ -270,6 +270,9 @@ public void Configure(XmlElement? element) /// </remarks> protected IAppender? ParseAppender(XmlElement appenderElement) { + // Configuration names the types to load and instantiate. This is by design: configuration is + // trusted input, see + // https://raw.githubusercontent.com/apache/logging-site/refs/heads/main/src/site/antora/modules/ROOT/pages/_threat-model-common.adoc string appenderName = appenderElement.EnsureNotNull().GetAttribute(NameAttr); string typeName = appenderElement.GetAttribute(TypeAttr); @@ -564,6 +567,8 @@ protected void SetParameter(XmlElement element, object target) MethodInfo? methInfo = null; // Try to find a writable property + // Non-public members are reachable on purpose: configuration is trusted input, see + // https://raw.githubusercontent.com/apache/logging-site/refs/heads/main/src/site/antora/modules/ROOT/pages/_threat-model-common.adoc PropertyInfo? propInfo = targetType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase); if (propInfo is not null && propInfo.CanWrite) {
