اليوم، نقوم بإصدار XenForo 2.2.17 لمعالجة ثغرة أمنية محتملة. نوصي بأن يقوم جميع العملاء الذين يستخدمون XenForo 2.2 بالترقية إلى الإصدار 2.2.17 أو استخدام تعليمات التصحيح أدناه في أقرب وقت ممكن.
ملاحظات:
أ. الإصدارات 2.3.1 وما فوق من XenForo غير متأثرة بهذه المسألة. إذا كنت لا تزال تستخدم XenForo 2.3.0، يجب عليك الترقية إلى أحدث إصدار أو تطبيق التصحيح أدناه.ب. تم تصحيح العملاء القليلين الذين يستخدمون نظام XenForo Cloud وما زالوا يعملون على الإصدار 2.2 تلقائيًا.
تتعلق المشكلة بإمكانية استغلال إعادة التوجيه باستخدام رابط تم صياغته بشكل خاص.
يتوجه فريق XenForo بالشكر إلى @mattrogowski، و @Jake B، وفريق @ThemeHouse لتنبيههم لنا بشأن هذه المشكلة.
نوصي بإجراء تحديث كامل لحل المشكلات، ولكن يمكن تطبيق تصحيح يدويًا. انظر أدناه للحصول على مزيد من التفاصيل.
تطبيق التصحيح يدويًا
الطريقة 1: تحرير الملف يدويًا يتطلب تطبيق التصحيح في هذه الحالة تعديل دالة واحدة داخل ملف محدد. للقيام بذلك، ابحث عن الملف src/XF/App.php وحدد بدء هذه الدالة المحددة:
اعثر على نهاية الدالة التي تبدو حاليًا هكذا:
احذف هذه الكتلة الكاملة من الكود واستبدلها بما يلي:
الطريقة 2: تطبيق التصحيح/الاختلاف
يمكنك تطبيق التصحيح التالي لتصحيح الملف تلقائيًا:
ملاحظة: إذا قررت تصحيح الملفات بدلاً من إجراء ترقية كاملة، فسوف يقوم "فحص صحة الملف" الخاص بك بالإبلاغ عن هذا الملف باعتباره يحتوي على "محتويات غير متوقعة". نظرًا لأن هذه الملفات لم تعد تحتوي على نفس المحتويات التي تم شحن إصدار XF بها، فمن المتوقع أن يحدث هذا ويمكن تجاهله بأمان.
كما هو الحال دائمًا، يمكن تنزيل الإصدارات الجديدة من XenForo مجانًا لجميع العملاء الذين لديهم تراخيص نشطة، والذين يمكنهم الآن الحصول على الإصدار الجديد من منطقة العملاء أو الترقية من لوحة التحكم الإدارية (أدوات > التحقق من الترقيات...).
ملاحظات:
أ. الإصدارات 2.3.1 وما فوق من XenForo غير متأثرة بهذه المسألة. إذا كنت لا تزال تستخدم XenForo 2.3.0، يجب عليك الترقية إلى أحدث إصدار أو تطبيق التصحيح أدناه.ب. تم تصحيح العملاء القليلين الذين يستخدمون نظام XenForo Cloud وما زالوا يعملون على الإصدار 2.2 تلقائيًا.
تتعلق المشكلة بإمكانية استغلال إعادة التوجيه باستخدام رابط تم صياغته بشكل خاص.
يتوجه فريق XenForo بالشكر إلى @mattrogowski، و @Jake B، وفريق @ThemeHouse لتنبيههم لنا بشأن هذه المشكلة.
نوصي بإجراء تحديث كامل لحل المشكلات، ولكن يمكن تطبيق تصحيح يدويًا. انظر أدناه للحصول على مزيد من التفاصيل.
تطبيق التصحيح يدويًا
الطريقة 1: تحرير الملف يدويًا يتطلب تطبيق التصحيح في هذه الحالة تعديل دالة واحدة داخل ملف محدد. للقيام بذلك، ابحث عن الملف 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;
}
الطريقة 2: تطبيق التصحيح/الاختلاف
يمكنك تطبيق التصحيح التالي لتصحيح الملف تلقائيًا:
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 مجانًا لجميع العملاء الذين لديهم تراخيص نشطة، والذين يمكنهم الآن الحصول على الإصدار الجديد من منطقة العملاء أو الترقية من لوحة التحكم الإدارية (أدوات > التحقق من الترقيات...).