CVE-2022-4563: Improper Link Resolution Before File Access ('Link Following') (CWE-59)
value: A vulnerability was found in Freedom of the Press SecureDrop. It has been rated as critical. Affected by this issue is some unknown functionality of the file gpg-agent.conf. The manipulation leads to symlink following. Local access is required to approach this attack. The name of the patch is b0526a06f8ca713cce74b63e00d3730618d89691. It is recommended to apply a patch to fix this issue. The identifier of this vulnerability is VDB-215972.
CWE description: The product attempts to access a file based on the filename, but it does not properly prevent that filename from identifying a link or shortcut that resolves to an unintended resource.
CVSS v3 base score: 7.8
Published: 2022-12-16T17:15Z
Repository: https://github.com/freedomofpress/securedrop
Language: Other
Files changed: securedrop/debian/securedrop-app-code.postinst
Commit date: 2022-12-08 13:19:46 -0500
Commit message: Manipulate gpg config file as www-data

An attacker with access to www-data could have gpg-agent.conf be a
symlink to a root-owned file (e.g. /etc/passwd) and trick the postinst
into clobbering that file as root. Because the content is fixed, it's
pretty low risk but straightforward to fix.

Diff: diff --git a/securedrop/debian/securedrop-app-code.postinst b/securedrop/debian/securedrop-app-code.postinst
index 5716eed24..e7bf91271 100644
--- a/securedrop/debian/securedrop-app-code.postinst
+++ b/securedrop/debian/securedrop-app-code.postinst
@@ -167,39 +167,41 @@ case "$1" in
     for dir in /var/lib/securedrop/{,tmp,shredder,store,keys,/keys/private-keys-v1.d,/keys/openpgp-revocs.d,backups}; do
       mkdir -p "$dir"
       chmod 0700 "$dir"
     done
 
+    chown -R www-data:www-data /var/lib/securedrop
+
     # Ensure required gpg-agent.conf is in place, see #4013.
     if [ -e "/var/lib/securedrop/keys/gpg-agent.conf" ]; then
 
         # gpg-agent.conf does exist, update it if needed.
         if ! grep -qE '^allow-loopback-pinentry$' /var/lib/securedrop/keys/gpg-agent.conf; then
-            echo allow-loopback-pinentry >> /var/lib/securedrop/keys/gpg-agent.conf
+            echo allow-loopback-pinentry | sudo -u www-data tee -a /var/lib/securedrop/keys/gpg-agent.conf
         fi
         if ! grep -qE '^default-cache-ttl 0$' /var/lib/securedrop/keys/gpg-agent.conf; then
-            echo 'default-cache-ttl 0' >> /var/lib/securedrop/keys/gpg-agent.conf
+            echo 'default-cache-ttl 0' | sudo -u www-data tee -a /var/lib/securedrop/keys/gpg-agent.conf
         fi
 
     else
         # gpg-agent.conf does not yet exist, create it.
-        echo allow-loopback-pinentry > /var/lib/securedrop/keys/gpg-agent.conf
-        echo 'default-cache-ttl 0' >> /var/lib/securedrop/keys/gpg-agent.conf
+        echo allow-loopback-pinentry | sudo -u www-data tee /var/lib/securedrop/keys/gpg-agent.conf
+        echo 'default-cache-ttl 0' | sudo -u www-data tee -a /var/lib/securedrop/keys/gpg-agent.conf
     fi
 
     # Migrate private keyring to gpg2.1 if needed
     if [ ! -d "/var/lib/securedrop/keys/private-keys-v1.d" ]; then
         # Then we should migrate the keyring
-        gpg2 --homedir=/var/lib/securedrop/keys --batch --import < /var/lib/securedrop/keys/secring.gpg
+        # shellcheck disable=SC2024
+        sudo -u www-data gpg2 --homedir=/var/lib/securedrop/keys --batch --import < /var/lib/securedrop/keys/secring.gpg
     fi
 
-    chown -R www-data:www-data /var/lib/securedrop
-
     # /var/www/securedrop should be owned by root and world-readable.
     # Permissions on specific files will be loosened after
     chown -R root:root /var/www/securedrop
     chmod 755 /var/www/securedrop
+
     # Make sure config.py is owned by root and readable by www-data,
     # but not world-readable
     if [ -f "/var/www/securedrop/config.py" ]; then
         chown root:www-data /var/www/securedrop/config.py
         chmod 640 /var/www/securedrop/config.py

Vulnerable code:             echo allow-loopback-pinentry >> /var/lib/securedrop/keys/gpg-agent.conf
            echo 'default-cache-ttl 0' >> /var/lib/securedrop/keys/gpg-agent.conf
        echo allow-loopback-pinentry > /var/lib/securedrop/keys/gpg-agent.conf
        echo 'default-cache-ttl 0' >> /var/lib/securedrop/keys/gpg-agent.conf
        gpg2 --homedir=/var/lib/securedrop/keys --batch --import < /var/lib/securedrop/keys/secring.gpg
    chown -R www-data:www-data /var/lib/securedrop

Fixed code:     chown -R www-data:www-data /var/lib/securedrop

            echo allow-loopback-pinentry | sudo -u www-data tee -a /var/lib/securedrop/keys/gpg-agent.conf
            echo 'default-cache-ttl 0' | sudo -u www-data tee -a /var/lib/securedrop/keys/gpg-agent.conf
        echo allow-loopback-pinentry | sudo -u www-data tee /var/lib/securedrop/keys/gpg-agent.conf
        echo 'default-cache-ttl 0' | sudo -u www-data tee -a /var/lib/securedrop/keys/gpg-agent.conf
        # shellcheck disable=SC2024
        sudo -u www-data gpg2 --homedir=/var/lib/securedrop/keys --batch --import < /var/lib/securedrop/keys/secring.gpg