Fix open redirect security issue (CWE-601)
authorChristian Weiske <cweiske@cweiske.de>
Fri, 26 Nov 2021 09:22:17 +0000 (10:22 +0100)
committerChristian Weiske <cweiske@cweiske.de>
Fri, 26 Nov 2021 09:23:06 +0000 (10:23 +0100)
You have to white-list allowed default URLs now.

See: https://cwe.mitre.org/data/definitions/601.html

Thanks to Daniel Aleksandersen for notifying me about the issue.

ChangeLog
data/surrogator.config.php.dist
www/avatar.php

index ec4443d72d7e8c9f8f77e4e6f513833c8ca38249..23984d68f95589d0f4084eafee6ef9b13bd085e1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2021-11-26  Christian Weiske  <cweiske@cweiske.de>
+
+       * Fix open redirect security issue (CWE-601).
+         You have to white-list allowed default URLs now.
+
 2012-08-27  Christian Weiske  <cweiske@bogo>
 
        * Add support for OpenIDs
index 23a1e8ab74f68a288a28408f06f1219d9017997f..f43372774a3f08c6b866257296c65d6b2b26ce36 100644 (file)
@@ -43,4 +43,20 @@ $logLevel = 1;
  * to true, the images will always be regenerated.
  */
 $forceUpdate = false;
+
+/**
+ * URL prefixes that may be used as "default" parameter.
+ *
+ * Taken from https://git.linux-kernel.at/oliver/ivatar/-/blob/master/config.py
+ */
+$trustedDefaultUrls = [
+    'http://gravatar.com/avatar/',
+    'http://www.planet-libre.org/themes/planetlibre/images/',
+    'https://avatars.dicebear.com/api/',
+    'https://badges.fedoraproject.org/static/img/',
+    'https://gravatar.com/avatar/',
+    'https://secure.gravatar.com/avatar/',
+    'https://ui-avatars.com/api/',
+    'https://www.azuracast.com/img/',
+];
 ?>
index e707dc40f7955b5cfb8912ae8b896896cca49056..e20ddda763d5146881527b0bf178c8c4daef5bcc 100644 (file)
@@ -96,7 +96,19 @@ if (isset($_GET['default'])) {
         //url
         $defaultMode = 'redirect';
         $default     = $_GET['default'];
-        //FIXME: validate?
+
+        $allowed = false;
+        foreach ($trustedDefaultUrls ?? [] as $urlPrefix) {
+            if (substr($default, 0, strlen($urlPrefix))  == $urlPrefix) {
+                $allowed = true;
+                break;
+            }
+        }
+        if (!$allowed) {
+            header('X-Info: default parameter URL not allowed');
+            $defaultMode = 'local';
+            $default     = 'default.png';
+        }
     }
 }
 
@@ -149,4 +161,4 @@ header('Content-Type: image/png');
 header('Content-Length:' . $stat['size']);
 
 readfile($imgFile);
-?>
\ No newline at end of file
+?>