This is an automated email from the ASF dual-hosted git repository.

FreeAndNil pushed a commit to branch Feature/312-more-hardening
in repository https://gitbox.apache.org/repos/asf/logging-log4net.git

commit 141cb8efb3714b3968f984bb51cbe6641b496fdf
Author: Jan Friedrich <[email protected]>
AuthorDate: Tue Sep 1 18:34:06 2026 +0200

    fix a signature verification bypass in the release scripts
    
    "wget URL" refuses to overwrite, so a KEYS file planted next to the
    artifacts stayed put, the real download landed in KEYS.1, and the planted
    keys were imported into the verification key ring. Artifacts signed by
    whoever placed it then verified and the script exited 0.
    
    Both scripts now download into the temporary key ring directory and never
    read KEYS from the directory being verified.
    
    Not a regression: the same fixture bypasses the pre-rewrite script, which
    carried the bare wget line from 3.2.0 on.
---
 scripts/verify-release.ps1                             | 10 +++++++---
 scripts/verify-release.sh                              | 11 ++++++++---
 src/changelog/3.4.1/312-verify-release-keys-bypass.xml | 14 ++++++++++++++
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/scripts/verify-release.ps1 b/scripts/verify-release.ps1
index 46e0ca02..ee2d538f 100644
--- a/scripts/verify-release.ps1
+++ b/scripts/verify-release.ps1
@@ -55,16 +55,20 @@ foreach ($Artifact in $Artifacts)
   Assert-Hash $Artifact
 }
 
-Invoke-WebRequest https://downloads.apache.org/logging/KEYS -OutFile 
$Directory/KEYS
-
 # A key ring of its own, holding only the downloaded KEYS. Importing into the 
default key ring
 # would accept a signature from any key this machine already has, not only 
from a key in the
 # Logging Services KEYS file.
 $KeyringDirectory = New-Item -ItemType Directory -Path (Join-Path 
([System.IO.Path]::GetTempPath()) ([guid]::NewGuid()))
 try
 {
+  # Downloaded into that directory, and never read from the one being 
verified: a KEYS file sitting
+  # next to the artifacts is not covered by any of the checks above, so 
importing it would let
+  # anyone who can place a file there have their own key accepted as a release 
key.
+  $Keys = Join-Path $KeyringDirectory 'KEYS'
+  Invoke-WebRequest https://downloads.apache.org/logging/KEYS -OutFile $Keys
+
   $Keyring = Join-Path $KeyringDirectory 'logging-keys.gpg'
-  gpg --no-default-keyring --keyring $Keyring --batch --quiet --import 
$Directory/KEYS
+  gpg --no-default-keyring --keyring $Keyring --batch --quiet --import $Keys
 
   foreach ($Artifact in $Artifacts)
   {
diff --git a/scripts/verify-release.sh b/scripts/verify-release.sh
index 7afd7100..6d8f6cc4 100644
--- a/scripts/verify-release.sh
+++ b/scripts/verify-release.sh
@@ -38,14 +38,19 @@ for file in "${artifacts[@]}"; do
   sha512sum --check "$file.sha512"
 done
 
-wget https://downloads.apache.org/logging/KEYS
-
 # A key ring of its own, holding only the downloaded KEYS. Importing into the 
default key ring
 # would accept a signature from any key this machine already has, not only 
from a key in the
 # Logging Services KEYS file.
 keyring_dir="$(mktemp -d)"
 trap 'rm -rf "$keyring_dir"' EXIT
-gpg --no-default-keyring --keyring "$keyring_dir/logging-keys.gpg" --batch 
--quiet --import KEYS
+
+# Downloaded into that directory, and never read from the one being verified. 
"wget URL" writes to
+# ./KEYS but refuses to overwrite, so with a KEYS file already sitting next to 
the artifacts the
+# download would land in KEYS.1 and the pre-existing file, which nothing here 
verifies, would be
+# the one imported. Anyone who can place a file in the directory could then 
have their own key
+# accepted as a release key.
+wget -O "$keyring_dir/KEYS" https://downloads.apache.org/logging/KEYS
+gpg --no-default-keyring --keyring "$keyring_dir/logging-keys.gpg" --batch 
--quiet --import "$keyring_dir/KEYS"
 
 for file in "${artifacts[@]}"; do
   if test ! -f "$file.asc"; then
diff --git a/src/changelog/3.4.1/312-verify-release-keys-bypass.xml 
b/src/changelog/3.4.1/312-verify-release-keys-bypass.xml
new file mode 100644
index 00000000..4e6e1852
--- /dev/null
+++ b/src/changelog/3.4.1/312-verify-release-keys-bypass.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xmlns="https://logging.apache.org/xml/ns";
+       xsi:schemaLocation="https://logging.apache.org/xml/ns 
https://logging.apache.org/xml/ns/log4j-changelog-0.xsd";
+       type="fixed">
+  <issue id="312" link="https://github.com/apache/logging-log4net/pull/312"/>
+  <description format="asciidoc">
+    stop the release verification scripts from importing a `KEYS` file that 
came with the artifacts
+ instead of the one they download. `wget` refuses to overwrite, so a planted 
`KEYS` stayed in place
+ and was imported into the verification key ring, and artifacts signed by 
whoever placed it verified
+ (CWE-347). The key ring is now filled from a copy downloaded to a temporary 
directory. Present in
+ 3.2.0 onward, since the script was added (audit da18b6fd-f003)
+  </description>
+</entry>

Reply via email to