В первой части я рассказал, как выделить наиболее критичные для abuse области приложения, и привел примеры из нескольких таких блоков. В этот раз рассказываю об остальных элементах приложения — и о том, зачем вообще нужно abuse-тестирование.
Напомню: речь идет о блоках приложения, цель которого — онлайн-экзаменация сотрудников, участвующих в грузовых авиаперевозках. У экзаменуемых есть желание получить более высокие результаты на экзамене и «считерить» при прохождении курса.
Области приложения
Таймер
Ожидание: при старте экзамена у студента начинается отсчет таймера, который останавливается только по факту его завершения (у студента может быть несколько экзаменов в курсе, поэтому таймер по факту завершения одного из них ставится на паузу, а по факту завершения всех экзаменов — останавливается окончательно, тем самым завершается курс). По факту истечения таймера должен завершаться весь курс и все экзамены, начать прохождение снова невозможно.
Как тестировать:
- Корректировка свойств таймера в DOM страницы.
- Правка локального времени на машине.
- Манипуляции с браузером: обнолвение страницы/закрытие вкладки/закрытие браузера/открытие в двух параллельных вкладках.
- Манипуляции со статусами (так как таймер стартовал по факту изменения статуса сценария с new в in progress).
- Манипуляции с сетью/запросом. Так как по факту истечения таймера отправляется запрос на сервер, наша задача — не допустить его отправку.
Итоговое решение на проекте: таймер работает только с серверным временем, так что, даже если студенту и удастся видоизменить его на интерфейсе, он все равно будет завершен в срок вне зависимости от других факторов.
Интересный факт: при тестировании подобных вещей важно понимать, какие факторы влияют на объект. В нашем случае это статус экзамена.
Там и был обнаружен баг: после старта экзамена и старта таймера перевод экзамена обратно в статус new давал возможность повторно его запустить, и таймер стартовал по новой. Пациент был вылечен добавлением валидации статусов, которая не давала возможности сменить статус на предыдущий (с in progress в new, с completed в in progress).
Переходы между секциями
Ожидание: у студента при прохождении сценария доступна для редактирования только та секция, на которой он находится. Перейти в предыдущие секции можно, но только для просмотра. Переход в последующие секции возможен только по факту завершения актуальной (завершение означает ответ на все вопросы и нажатие кнопки Next).
Как тестировать:
- Корректировка свойств секции в DOM страницы. Установка значения Enabled/Active по неактивной секции, отвеченным вопросам и т.д.
- Прохождение в нескольких вкладках браузера: завершение секции в одной и отсутствие действий на другой.
- Обновление страницы, закрытие и повторное открытие вкладок.
- Замена ответов напрямую посредством API.
Итоговое решение на проекте: в базе данных у нас не было секций. Другими словами, бэкенд проекта и не догадывался, что мы что-то блокируем и имеем разделение вопросов, а все вопросы хранились в одном месте. Поэтому пришли к компромиссу в виде валидации на фронтенде и закрепили это решение с заказчиком.
В этом случае потенциальный читер имеет возможность через API менять ответы на вопросы в секциях, которые уже были завершены, но только в рамках экзамена и в рамках отведенного для этого времени, что не слишком критично.
Завершение экзамена
Ожидание: по факту нажатия на кнопку «Завершить» (становится активной после ответа на все вопросы экзамена) студент перенаправлялся на страницу курса с доступными экзаменами или на страницу результатов курса, если экзамен был последним в курсе. Теоретически завершение экзамена — это отправка запроса с данными экзамена и смена его статуса с in progress на completed.
Как тестировать:
- Попытки завершить экзамен в разных вкладках браузера с разными ответами последовательно или одновременно, используя REST клиент.
- Попытки завершить экзамен, который не в статусе in progress.
- Попытки завершить экзамен без полного набора ответов.
- Смена ответа по факту завершения экзамена посредством API.
Итоговое решение на проекте: реализация валидации статуса экзамена — возможность завершить экзамен только в статусе in progress и только один раз. Добавлена валидация в вопросы: при ответах учитывается статус экзамена.
Действия с завершенным курсом и результатами
Ожидание: По факту завершения последнего экзамена в курсе (если он один, то завершение экзамена = завершение курса) либо истечения таймера завершаются все экзамены и вычисляются результаты курса. Студент может просмотреть завершенные экзамены, свои ответы и их результаты. Отсутствие возможности изменить результаты сценария или повторно его пройти.
Как тестировать:
- Манипуляции со статусом курса — попытки сменить его на new
- Проверка возможности через API или интерфейс пользователя корректировать уже завершенные экзамены.
- Проверка возможности подмены/корректировки результатов курса.
Итоговое решение на проекте: любой ответ на вопрос сразу записывается в базу, чтобы на финальном комплите не иметь большой запрос. Это также решило проблему сброса ответов при обновлении страницы или повторном входе в экзамен. Добавлена валидация, не позволяющая проводить манипуляции с экзаменом и его вопросами, когда он не в статусе in progress.
Манипуляции с результатами экзамена на интерфейсе не актуальны, так как заказчик будет вручную посредством API получать результаты по конкретным экзаменам, а отдавать эти результаты мы будем готовы только после верификации админского токена.
Что в итоге?
Однозначно могу сказать, что abuse-тестирование — это интересно, оно заставляет фантазию работать и генерировать идеи.
Обман системы — когда он во благо — это идеальная почва для развития.
Четкого лекала здесь нет, и хотя этот вид тестирования и можно частично отнести к security-тестированию, по большому счету это не так.
Наш проект на конкретном примере показал, что security-команда без полного понимания домена и нюансов приложения не сможет полностью покрыть тестами то, что можно протестировать с помощью abuse-тестирования.
Этот материал – не редакционный, это – личное мнение его автора. Редакция может не разделять это мнение.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: