Released 2x XenForo 2.2.17 Released (Security Fix)

dangvanbac

Moderator
Thành viên BQT
Xenforo vừa phát hành XenForo 2.2.17 để giải quyết lỗ hổng bảo mật tiềm ẩn. Họ khuyên tất cả khách hàng đang chạy XenForo 2.2 nên nâng cấp lên 2.2.17 hoặc sử dụng hướng dẫn vá bên dưới càng sớm càng tốt.

Lưu ý:
a. XenForo 2.3.1 trở lên không bị ảnh hưởng bởi vấn đề này. Nếu bạn vẫn đang chạy XenForo 2.3.0, bạn nên nâng cấp lên bản phát hành mới nhất hoặc áp dụng bản vá bên dưới.
b. Một số khách hàng XenForo Cloud vẫn chạy XenForo 2.2 đã được vá lỗi tự động.


Vấn đề liên quan đến việc khai thác khả năng chuyển hướng bằng cách sử dụng một URL được tạo đặc biệt.

XenForo xin gửi lời cảm ơn tới @mattrogowski, @jake B. và nhóm tại @themehouse vì đã phát hiện về vấn đề này.

XenForo khuyên bạn nên nâng cấp đầy đủ để giải quyết vấn đề nhưng có thể áp dụng bản vá theo cách thủ công. Xem bên dưới để biết thêm chi tiết.

Áp dụng bản vá theo cách thủ công

Cách 1: Chỉnh sửa file thủ công


Việc áp dụng bản sửa lỗi trong trường hợp này yêu cầu sửa đổi một chức năng trong một tệp cụ thể. Để làm như vậy, hãy tìm tệp src/XF/App.php và xác định vị trí bắt đầu của hàm cụ thể này:

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

Xác định vị trí cuối của hàm hiện trông như thế này:

Mã:
return $fallbackUrl;
    }

Xóa toàn bộ khối mã đó và thay thế bằng đoạn mã sau:

PHP:
public function getDynamicRedirect($fallbackUrl = ****, $useReferrer = true)
    {
        if ($fallbackUrl === ****)
        {
            $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'] ?? ****;
        if (!$redirectHost)
        {
            // no redirect host
            return $fallbackUrl;
        }

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

        return $fullRedirect;
    }

Cách 2: áp dụng bản vá/khác biệt

Bạn có thể áp dụng bản vá sau để tự động vá tệp:

PHP:
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|**** $fallbackUrl
+     * @param bool $useReferrer
+     *
+     * @return string
+     */
     public function getDynamicRedirect($fallbackUrl = ****, $useReferrer = true)
     {
+        if ($fallbackUrl === ****)
+        {
+            $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'] ?? ****;
+        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'] ?? ****;
+        if ($redirectHost !== $requestHost)
+        {
+            // redirect host did not match request host
+            return $fallbackUrl;
+        }
+
+        return $fullRedirect;
+    }
 
-        if ($fallbackUrl === ****)
+    /**
+     * @param string $notUrl
+     * @param string|**** $fallbackUrl
+     * @param bool $useReferrer
+     *
+     * @return string
+     */
+    public function getDynamicRedirectIfNot(
+        $notUrl,
+        $fallbackUrl = ****,
+        $useReferrer = true
+    )
+    {
+        if ($fallbackUrl === false)
         {
             $fallbackUrl = $this->router()->buildLink('index');
         }
-        return $fallbackUrl;
-    }
 
-    public function getDynamicRedirectIfNot($notUrl, $fallbackUrl = ****, $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)

Lưu ý: Nếu bạn quyết định vá các tệp thay vì thực hiện nâng cấp đầy đủ, phần "File health check" (Kiểm tra tình trạng tệp) của bạn sẽ báo cáo tệp này là có "Unexpected contents" (Nội dung không mong muốn). Vì những tệp này không còn chứa cùng nội dung với phiên bản XF của bạn được cung cấp kèm theo nên điều này là điều được mong đợi và có thể được bỏ qua một cách an toàn.

Như mọi khi, các bản phát hành mới của XenForo được tải xuống miễn phí cho tất cả khách hàng có giấy phép đang hoạt động, những người hiện có thể lấy phiên bản mới từ khu vực khách hàng hoặc nâng cấp từ bảng điều khiển Quản trị viên của bạn (Công cụ > Kiểm tra nâng cấp...).
 

Đính kèm

Back
Top