В этом разделе нужно описать пререквизиты и примеры запуска Стандартно сделать venv, активировать, поставить депенденси и запустить локальный сервер:
python -m venv env
source env/bin/activate
pip install -r requirements.txt
python vulnapp/manage.py runserver
И поставить exiftool apt install exiftool.
Тк БД sqlite есть в репо, то миграции делать ненужно.
Чтобы воспользоватся приложением, надо зайти на http://127.0.0.1:8000/. Чтобы зарегистрировать аккаунт можно просто нажать на "Create new post", он перенесет на страницу авторизации автоматически. Тамже и есть кнопка перехода на регистрацию аккаунта.
Далее можно создавать посты которые увидят другие пользователи.
Основные идеи исправлений для реализованных уязвимостей нужно описать в этом разделе.
Уязвимость XSS появляется тк мы хотим рендерить в контенте сообщений не только просто текст, а хотим потом прикрутить туда WYSIWYG редактор. Тк WYSIWYG редактор отправляет контент в виде чистого HTML, то если его не санитизировать то будет Stored-XSS.
Для санитайзинга использовал мозиловский bleach:
def form_valid(self, form):
# Set the owner of the model instance to the current user
form.instance.owner = self.request.user
form.instance.content = bleach.clean(form.instance.content)
return super().form_valid(form)
На сайте есть возможность удалять сообщения. Для этого посылается POST запрос на delete/int:pk. Тк айди можно послать чужого сообщения, то получится что чужой пользователь может удалить сообщение. Для этого я реализовал проверку obj.owner != self.request.user
.
Для проверки IDOR можно зарегать 2 аккаунта, и создать сообщение которое надо удалить. Потом через devtools можно скопировать copy as curl, и заменить ID картинки на чужой.
Тк использовал ORM для всех запросов, то инъекций нету.
Тк exiftool subprocess.run запускается без shell=True, то инъекция команд невозможна.
Для фикса проблем с траверсалом использовал метод белого списка. Перед тем как отдать контент, проверяется если имя файла есть в БД.
image_found_in_db = BoardPost.objects.filter(image='user_uploads/'+file_name).first()
if not image_found_in_db:
return HttpResponse("Filename not allowed", status=403)
Тк exiftool в get_exif_data запускается от недоверенных путей, то в него тоже добавил проверку на path traversal.
Использовал Django-axe он ставит ограничения на скорость попыток по айпи. В джанге встроенная парольная политика очень жесткая, поэтому брутфорс невозможен.
Для простоты проверки на IDOR я выключил CSRF милдлварь.