XenForo 2.2

程序包 XenForo 2.2 2.2.17

没有下载权限

XenForo 2.2.17 发布(安全修复)​


今天,我们发布了 XenForo 2.2.17 以解决潜在的安全漏洞。我们建议所有运行 XenForo 2.2 的客户尽快升级到 2.2.17 或使用下面的补丁说明。

注意:

a. XenForo 2.3.1 及更高版本不受此问题的影响。如果您仍在运行 XenForo 2.3.0,则应升级到最新版本或应用以下补丁。
湾。少数仍在运行 XenForo 2.2 的 XenForo Cloud 客户已自动修补。


该问题与使用特制 URL 的潜在重定向漏洞有关。

XenForo 感谢 @mattrogowski、@Jake B. 和 @ThemeHouse 的团队让我们意识到这个问题。

我们建议执行完全升级以解决问题,但可以手动应用补丁。有关更多详细信息,请参阅下文。


在这种情况下,应用修复需要修改特定文件中的单个函数。为此,请找到文件 src/XF/App.php 并找到此特定函数的开头:

PHP:
    public function getDynamicRedirect($fallbackUrl = null, $useReferrer = true)


找到函数的末尾,当前如下所示:

PHP:
        return $fallbackUrl;
    }


删除整个代码块并替换为以下内容:

PHP:
    public function getDynamicRedirect($fallbackUrl = null, $useReferrer = true)
    {
        if ($fallbackUrl === null)
        {
            $fallbackUrl = $this->router()->buildLink('index');
        }

        $request = $this->request();
        $fallbackUrl = $request->convertToAbsoluteUri($fallbackUrl);

        $redirect = $request->filter('_xfRedirect', 'str');
        if (!$redirect && $useReferrer)
        {
            $redirect = $request->getServer('HTTP_X_AJAX_REFERER')
                ?: $request->getReferrer();
        }

        if (!$redirect || !preg_match('/./su', $redirect))
        {
            // no redirect provided
            return $fallbackUrl;
        }

        if (
            strpos($redirect, "\n") !== false ||
            strpos($redirect, "\r") !== false ||
            strpos($redirect, '@') !== false
        )
        {
            // redirect contained newlines or user/pass
            return $fallbackUrl;
        }

        $fullRedirect = $request->convertToAbsoluteUri($redirect);
        $redirectParts = @parse_url($fullRedirect);
        $redirectHost = $redirectParts['host'] ?? null;
        if (!$redirectHost)
        {
            // no redirect host
            return $fallbackUrl;
        }

        $requestParts = @parse_url($request->getFullBasePath());
        $requestHost = $requestParts['host'] ?? null;
        if ($redirectHost !== $requestHost)
        {
            // redirect host did not match request host
            return $fallbackUrl;
        }

        return $fullRedirect;
    }

您可以应用以下修补程序来自动修补文件:

Diff:
Index: src/XF/App.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/XF/App.php b/src/XF/App.php
--- a/src/XF/App.php    (revision 7f4538e8ad4a572dcff3e0416b56906ec84a53eb)
+++ b/src/XF/App.php    (revision 5a8b3ebd97eae9bc82d4f6aac5f17012d27b0043)
@@ -2305,50 +2305,85 @@
         return '__' . $hash;
     }
 
+    /**
+     * @param string|null $fallbackUrl
+     * @param bool $useReferrer
+     *
+     * @return string
+     */
     public function getDynamicRedirect($fallbackUrl = null, $useReferrer = true)
     {
+        if ($fallbackUrl === null)
+        {
+            $fallbackUrl = $this->router()->buildLink('index');
+        }
+
         $request = $this->request();
+        $fallbackUrl = $request->convertToAbsoluteUri($fallbackUrl);
 
         $redirect = $request->filter('_xfRedirect', 'str');
         if (!$redirect && $useReferrer)
         {
-            $redirect = $request->getServer('HTTP_X_AJAX_REFERER');
-            if (!$redirect)
-            {
-                $redirect = $request->getReferrer();
-            }
+            $redirect = $request->getServer('HTTP_X_AJAX_REFERER')
+                ?: $request->getReferrer();
+        }
+
+        if (!$redirect || !preg_match('/./su', $redirect))
+        {
+            // no redirect provided
+            return $fallbackUrl;
         }
 
-        if ($redirect && preg_match('/./su', $redirect))
+        if (
+            strpos($redirect, "\n") !== false ||
+            strpos($redirect, "\r") !== false ||
+            strpos($redirect, '@') !== false
+        )
         {
-            if (strpos($redirect, "\n") === false && strpos($redirect, "\r") === false)
-            {
-                $fullBasePath = $request->getFullBasePath();
+            // redirect contained newlines or user/pass
+            return $fallbackUrl;
+        }
 
-                $fullRedirect = $request->convertToAbsoluteUri($redirect);
-                $redirectParts = @parse_url($fullRedirect);
-                if ($redirectParts && !empty($redirectParts['host']))
-                {
-                    $pageParts = @parse_url($fullBasePath);
+        $fullRedirect = $request->convertToAbsoluteUri($redirect);
+        $redirectParts = @parse_url($fullRedirect);
+        $redirectHost = $redirectParts['host'] ?? null;
+        if (!$redirectHost)
+        {
+            // no redirect host
+            return $fallbackUrl;
+        }
 
-                    if ($pageParts && !empty($pageParts['host']) && $pageParts['host'] == $redirectParts['host'])
-                    {
-                        return $fullRedirect;
-                    }
-                }
-            }
-        }
+        $requestParts = @parse_url($request->getFullBasePath());
+        $requestHost = $requestParts['host'] ?? null;
+        if ($redirectHost !== $requestHost)
+        {
+            // redirect host did not match request host
+            return $fallbackUrl;
+        }
+
+        return $fullRedirect;
+    }
 
-        if ($fallbackUrl === null)
+    /**
+     * @param string $notUrl
+     * @param string|null $fallbackUrl
+     * @param bool $useReferrer
+     *
+     * @return string
+     */
+    public function getDynamicRedirectIfNot(
+        $notUrl,
+        $fallbackUrl = null,
+        $useReferrer = true
+    )
+    {
+        if ($fallbackUrl === false)
         {
             $fallbackUrl = $this->router()->buildLink('index');
         }
-        return $fallbackUrl;
-    }
 
-    public function getDynamicRedirectIfNot($notUrl, $fallbackUrl = null, $useReferrer = true)
-    {
         $request = $this->request();
+        $fallbackUrl = $request->convertToAbsoluteUri($fallbackUrl);
 
         $redirect = $this->getDynamicRedirect($fallbackUrl, $useReferrer);
         $notUrl = $request->convertToAbsoluteUri($notUrl);
@@ -2356,17 +2391,10 @@
         if (strpos($redirect, $notUrl) === 0)
         {
             // the URL we can't redirect to is at the start
-            if ($fallbackUrl === false)
-            {
-                $fallbackUrl = $this->router()->buildLink('index');
-            }
+            return $fallbackUrl;
+        }
 
-            return $request->convertToAbsoluteUri($fallbackUrl);
-        }
-        else
-        {
-            return $redirect;
-        }
+        return $redirect;
     }
 
     public function applyExternalDataUrl($externalPath, $canonical = false)


注意:如果您决定修补文件而不是进行完全升级,则“文件运行状况检查”会将此文件报告为“意外内容”。因为这些文件不再包含与您的 XF 版本一起提供的相同内容,所以这是意料之中的,可以安全地忽略。

与往常一样,所有拥有有效许可证的客户都可以免费下载 XenForo 的新版本,他们现在可以从客户区获取新版本,也可以从您的管理员控制面板进行升级(工具>检查升级...)。
后退
顶部 底部