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>
