Загальні помилки конфігурації можуть призвести до неналежного контролю доступу на шляху завантаження django-mdeditor.

pic

I. Що таке django-mdeditor?

django-mdeditor — це популярний відкритий проект для Django, який надає зручний редактор markdown для вебсайтів, підтримуючи завантаження медіафайлів та живий перегляд. Цей редактор можна інтегрувати як безпосередньо в шаблони, так і в адмін-панель Django через клас MDTextField.

II. Проблеми з безпекою

За замовчуванням, додаток не обробляє завантаження файлів у нейтральний спосіб. Він використовує клас UploadView для обробки завантажень, і поведінка цього виду налаштовується в settings.py через MDEDITOR_CONFIGS. Проблема полягає в тому, що цей вид не реалізує контроль доступу за замовчуванням.

class UploadView(generic.View):  
 """ Завантаження зображень """  

 @method_decorator(csrf_exempt)  
 def dispatch(self, *args, **kwargs):  
 return super(UploadView, self).dispatch(*args, **kwargs)  
 def post(self, request, *args, **kwargs):  
 upload_image = request.FILES.get("editormd-image-file", None)  
 media_root = settings.MEDIA_ROOT  
 # перевірка на відсутність зображення  
 if not upload_image:  
 return JsonResponse({  
 'success': 0,  
 'message': "未获取到要上传的图片",  
 'url': ""  
 })  
 # перевірка формату зображення  
 file_name_list = upload_image.name.split('.')  
 file_extension = file_name_list.pop(-1)  
 file_name = '.'.join(file_name_list)  
 if file_extension not in MDEDITOR_CONFIGS['upload_image_formats']:  
 return JsonResponse({  
 'success': 0,  
 'message': "上传图片格式错误,允许上传图片格式为:%s" % ','.join(  
 MDEDITOR_CONFIGS['upload_image_formats']),  
 'url': ""  
 })  
 # перевірка папки для зображень  
 file_path = os.path.join(media_root, MDEDITOR_CONFIGS['image_folder'])  
 if not os.path.exists(file_path):  
 try:  
 os.makedirs(file_path)  
 except Exception as err:  
 return JsonResponse({  
 'success': 0,  
 'message': "上传失败:%s" % str(err),  
 'url': ""  
 })  
 # збереження зображення  
 file_full_name = '%s_%s.%s' % (file_name,  
 '{0:%Y%m%d%H%M%S%f}'.format(datetime.datetime.now()),  
 file_extension)  
 with open(os.path.join(file_path, file_full_name), 'wb+') as file:  
 for chunk in upload_image.chunks():  
 file.write(chunk)  
 return JsonResponse({'success': 1,  
 'message': "上传成功!",  
 'url': os.path.join(settings.MEDIA_URL,  
 MDEDITOR_CONFIGS['image_folder'],  
 file_full_name)})

Це може призвести до ситуацій, коли для використання редактора може знадобитися аутентифікація (наприклад, через адмін-панель Django), але завантаження файлів не вимагає цього.

III. Наслідки

Найпростішим способом використання цієї вразливості є атака типу Denial of Service (DoS) через файлову систему, що впливає на доступність.

Крім того, це може бути використано для підвищення прихованості під час атаки. Наприклад, якщо уразливий сайт https://jobs.ecorp.com, неавтентифікований атакувальник може завантажити і отримати зловмисні корисні навантаження, розміщені на цьому домені, що допоможе уникнути виявлення через фільтрацію DNS.

IV. Запропоновані виправлення

Тимчасове виправлення

Негайним виправленням буде декорування виду завантаження через login_required для забезпечення аутентифікації. Наприклад, замість того, щоб слідувати README.md проекту:

urlpatterns = [  
 ...  
 url(r'mdeditor/', include('mdeditor.urls')),  
 ...  
]

Ви можете зареєструвати вид і обгорнути його декоратором login_required:

urlpatterns = [  
 ...  
 path('mdeditor/uploads/', login_required(UploadView.as_view()), name='uploads'),  
 ...  
]

Постійне виправлення

Постійним рішенням може бути використання цього форка, який я створив для цього додатку, і відповідна зміна MDEDITOR_CONFIGS. Проблема в тому, що завантаження все ще не обробляється в нейтральний спосіб.

Альтернативно, за рахунок порушення сумісності з додатками, що залежать від цього пакету, більш надійним рішенням було б створити ще один форк, який повністю видалить UploadView і використовуватиме HTTP-коди повернення для зворотного зв'язку замість того, щоб читати JSON-відповіді на фронтенді.
Це, по суті, залишить завдання обробки завантажень на стороні серверу для розробників, надаючи їм повний контроль над безпекою.

Посилання

Перекладено з: Common misconfig may lead to Improper Access Control on django-mdeditor’s upload path

Leave a Reply

Your email address will not be published. Required fields are marked *