]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Make all hash algorithms available (but whitelist by default)
authorMikael Nordfeldth <mmn@hethane.se>
Tue, 28 Jun 2016 09:51:11 +0000 (11:51 +0200)
committerMikael Nordfeldth <mmn@hethane.se>
Tue, 28 Jun 2016 09:54:39 +0000 (11:54 +0200)
sha1 is whitelisted only because StatusNet requires it.

lib/default.php
plugins/OStatus/classes/FeedSub.php

index 12e194f54986ccbff797a29067ffd3cfb3f74b36..b3685a284c6fb61db8341c0792ae40534d6552de 100644 (file)
@@ -64,6 +64,9 @@ $default =
               'notice' => null, // site wide notice text
               'build' => 1, // build number, for code-dependent cache
               ),
+        'security' =>
+        array('hash_algos' => ['sha1', 'sha256', 'sha512'],   // set to null for anything that hash_hmac() can handle (and is in hash_algos())
+        ),
         'db' =>
           array('database' => null, // must be set
               'schema_location' => INSTALLDIR . '/classes',
index 72746e9b90dd76588e086613de0d9125eac5dee4..13a5439421812d56525ff6d7345590fbad550eb1 100644 (file)
@@ -442,10 +442,10 @@ class FeedSub extends Managed_DataObject
      */
     public function receive($post, $hmac)
     {
-        common_log(LOG_INFO, __METHOD__ . ": packet for \"" . $this->getUri() . "\"! $hmac $post");
+        common_log(LOG_INFO, sprintf(__METHOD__.': packet for %s with HMAC %s', _ve($this->getUri()), _ve($hmac)));
 
         if (!in_array($this->sub_state, array('active', 'nohub'))) {
-            common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH for inactive feed " . $this->getUri() . " (in state '$this->sub_state')");
+            common_log(LOG_ERR, sprintf(__METHOD__.': ignoring PuSH for inactive feed %s (in state %s)', _ve($this->getUri()), _ve($this->sub_state)));
             return;
         }
 
@@ -480,7 +480,7 @@ class FeedSub extends Managed_DataObject
      * shared secret that was set up at subscription time.
      *
      * If we don't have a shared secret, there should be no signature.
-     * If we we do, our the calculated HMAC should match theirs.
+     * If we do, our calculated HMAC should match theirs.
      *
      * @param string $post raw XML source as POSTed to us
      * @param string $hmac X-Hub-Signature HTTP header value, or empty
@@ -489,29 +489,36 @@ class FeedSub extends Managed_DataObject
     protected function validatePushSig($post, $hmac)
     {
         if ($this->secret) {
-            if (preg_match('/^sha1=([0-9a-fA-F]{40})$/', $hmac, $matches)) {
-                $their_hmac = strtolower($matches[1]);
-                $our_hmac = hash_hmac('sha1', $post, $this->secret);
+            // {3,16} because shortest hash algorithm name is 3 characters (md2,md4,md5) and longest
+            // is currently 11 characters, but we'll leave some margin in the end...
+            if (preg_match('/^([0-9a-zA-Z\-\,]{3,16})=([0-9a-fA-F]+)$/', $hmac, $matches)) {
+                $hash_algo  = strtolower($matches[1]);
+                $their_hmac = strtolower($matches[2]);
+                common_debug(sprintf(__METHOD__ . ': PuSH from feed %s uses HMAC algorithm %s with value: %s', _ve($this->getUri()), _ve($hash_algo), _ve($their_hmac)));
+
+                if (!in_array($hash_algo, hash_algos())) {
+                    // We can't handle this at all, PHP doesn't recognize the algorithm name ('md5', 'sha1', 'sha256' etc: https://secure.php.net/manual/en/function.hash-algos.php)
+                    common_log(LOG_ERR, sprintf(__METHOD__.': HMAC algorithm %s unsupported, not found in PHP hash_algos()', _ve($hash_algo)));
+                    return false;
+                } elseif (!is_null(common_config('security', 'hash_algos')) && !in_array($hash_algo, common_config('security', 'hash_algos'))) {
+                    // We _won't_ handle this because there is a list of accepted hash algorithms and this one is not in it.
+                    common_log(LOG_ERR, sprintf(__METHOD__.': Whitelist for HMAC algorithms exist, but %s is not included.', _ve($hash_algo)));
+                    return false;
+                }
+
+                $our_hmac = hash_hmac($hash_algo, $post, $this->secret);
                 if ($their_hmac === $our_hmac) {
                     return true;
                 }
-                if (common_config('feedsub', 'debug')) {
-                    $tempfile = tempnam(sys_get_temp_dir(), 'feedsub-receive');
-                    if ($tempfile) {
-                        file_put_contents($tempfile, $post);
-                    }
-                    common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH with bad SHA-1 HMAC: got $their_hmac, expected $our_hmac for feed " . $this->getUri() . " on $this->huburi; saved to $tempfile");
-                } else {
-                    common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH with bad SHA-1 HMAC: got $their_hmac, expected $our_hmac for feed " . $this->getUri() . " on $this->huburi");
-                }
+                common_log(LOG_ERR, sprintf(__METHOD__.': ignoring PuSH with bad HMAC hash: got %s, expected %s for feed %s from hub %s', _ve($their_hmac), _ve($our_hmac), _ve($this->getUri()), _ve($this->huburi)));
             } else {
-                common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH with bogus HMAC '$hmac'");
+                common_log(LOG_ERR, sprintf(__METHOD__.': ignoring PuSH with bogus HMAC==', _ve($hmac)));
             }
         } else {
             if (empty($hmac)) {
                 return true;
             } else {
-                common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH with unexpected HMAC '$hmac'");
+                common_log(LOG_ERR, sprintf(__METHOD__.': ignoring PuSH with unexpected HMAC==%s', _ve($hmac)));
             }
         }
         return false;