среда, 4 октября 2017 г.

Функциональные тесты превращаются... в тестирование на SQL инъекции!

Всем привет,

как правило, у любого проекта сначала появляется код, потом функциональные тесты, и только потом (возможно) проводится тестирование безопасности.
В этой статье я расскажу как вы можете быстро подготовить и провести сессию тестирования безопасности (пока только проверка на SQL инъекции) вашего продукта, используя уже готовый набор ваших функциональных тестов.

В чем преимущества:
  1. Для такой сессии тестирования вам потребуется только настроить тестовое окружение и запустить все функциональные тесты, после чего можно приступать к сканированию на SQL-инъекции. Это не потребует особой квалификации и больше чем несколько часов для подготовки. Вы можете сделать это прямо сегодня!
  2. Используем только бесплатные компоненты с открытым исходным кодом.

И так, начнем.
  1. Скачиваем и распаковываем SQLmap:
  1. Скачиваем и устанавливаем Burb Proxy:
  1. Запускаем Burb Suite, он запустит прокси на порту 8080 (по умолчанию, в UI это можно изменить).

В Burb proxy на вкладке Intercept не забываем выключить Intercept, чтобы он не захватывал запросы, а просто логировал их.

  1. Настраиваем прокси на Linux хосте, откуда будем запускать тесты, для этого вбиваем в bash консоль такие команды:


export HTTP_PROXY=127.0.0.1:8080
export HTTPS_PROXY=127.0.0.1:8080
здесь 127.0.0.1 - адрес Burb Proxy, 8080 - порт, который слушает прокси. Если вы запускаете прокси на одной машинке, а тесты запускате с другой машинки, тогда вам надо изменить эти параметры. В моем примере все компоненты работают на одной и той же машинке.
  1. Запускаем наши автоматические тесты (у меня тесты написаны на PyTest, но это могут быть так же любые другие тесты, главное - убедитесь, что ваши тесты отправляют запросы через прокси - в Burb UI на вкладке Proxy > HTTP History должны появиться новые записи):
pytest -n 30 tests/lbs

  1. Переключаемся обратно на Burb UI, переходим на вкладку Target > Site Map, щелкаем правой кнопкой мыши на адрес, куда обращались наши автоматизированные тесты (для каждого тестируемого сервиса здесь будет отдельная строка). В выпадающем меню выбираем пункт 'Save Selected Items' и сохраняем все это в файл test001.txt.
  1. Переходим в дирректорию с sqlmap и запускаем сканирование:
./sqlmap.py --batch -l test001.txt
Опция --batch заставляем sqlmap сканировать все, что дали, не спрашивая на каждом шаге подтверждение от пользователя, опция -l указывает SQLmap, что надо брать список "целей" из файла с логами от прокси сервера.

Если вы тестируете не production окружение, то лучше запустить так (это увеличит список проверок, которые сделает SQLmap):
./sqlmap.py --batch --level 5 --risk 3 -l test001.txt
  1. Анализируем всё, что выдаст нам SQLmap, открываем баг трекер и записываем результаты эксперимента ;)

Небольшой совет №1:
Создайте различные сущности в своем сервисе и сделайте тесты, которые будут их читать / изменять, чтобы в список запросов попали запросы работы с существующими в системе ресурсами. Если ваши тесты полностью очищают после себя все ресурсы SQLmap будет сложно найти уязвимости, ведь на многие запросы он получит 400/404 ошибки, просто потому что этих ресурсов и ссылок уже не существует.

Небольшой совет №2:
Почитайте вывод команды
./sqlmap.py --hh
Для тех, кто предпочитает делать все через UI - есть возможность установить sqlmap плагин прямо в Burb Proxy (хотя для этого потребуется поставить всякие зависимости, за то красиво):

пятница, 4 августа 2017 г.

Новый блог :)

Так как последнее время в свободное время я активно занялся разработкой Android игр, то решил завести блог, в котором я буду записывать какие-то ценные для себя мысли и идеи, а так же публиковать анонсы моих новых игр :)

Вот новый блог (вдруг кому будет интересно подписаться и читать :) ):
https://xwizard-mobile-games.blogspot.ru

четверг, 20 июля 2017 г.

PyTest: красивые имена тестов в репортиках

Последнее время довольно много приходится работать с PyTest, и несколько месяцев назад я написал небольшой кусочек кода, который позволяет переопределять имена тест кейсов через doc strings к ним.

Зачем это нужно?

Когда показываешь отчет о проделанном тестировании человеку, который не занимается запуском и написанием тестов, то имена тестовых сценариев им не говорят ни о чем, и выглядит такой отчет очень неаккуратно (он же автосгенерирован на основе кода).

Еще одним минусом является то, что очень сложно определить по такому отчету то, какие кейсы уже покрыты, а какие еще нет - так и хочется залезть в код функции теста, чтобы в этом разобраться.
Когда же у нас есть возможность описать тестовый сценарий в подробном doc string применяя обычные предложения на английском - у нас есть полная свобода в описании тестового сценария, и это описание можно импортировать в чек листы, в отчеты, в баг репорты и куда угодно еще.

Как было - список тестовых сценариев (пример запуска pytest --collect-only):

Как стало - список тестовых сценариев (пример запуска pytest --collect-only):

вторник, 18 июля 2017 г.

Дополнительные проверки не помешают

Сегодня мне довелось пользоваться супер продвинутым сканером безопасности (название и создатели которого останутся за NDA). Сканер реально крут.

Разобрался с параметрами, создал тестовый стенд, запустил сканер - задача на сканирование ушла в in progress и можно идти пить кофе - красота!

Вот кофе закончился - проверяем результаты сканирования.

Сканер радостно сообщает мне, что "все проверено, ни одной уязвимости не найдено!". На страничке с репортом даже вставлена прикольная смешная картинка чтобы порадовать пользователя:



Что еще нужно, да? :)

Написал разработчикам сканера - спросил как бы мне посмотреть детальный репорт - что проверялось, что отвечал сервер...

Оказалось, что мой сервер вообще не доступен в той сети, где живет сканер, и ни одна из проверок не запустилась. И если бы я не решил проверить ту информацию, что сообщает мне автоматизированный сканер (к которому у меня очень высокий уровень доверия) - то я бы этого никогда не узнал.

Так что проверяйте и перепроверяйте. Даже если кажется что все "проверено" и "работает"... ;)

Интересное наблюдение - в данном случае у меня стригерилась в голове моя любовь к циферкам - захотелось посмотреть сколько же тестов пройдено и что они там писали в логах.

И да, я оказался первым, кто вообще захотел это проверить... и вот это уже наводит на мысли о том как устроено человеческое сознание - "нет проблем" и веселая картинка, которая выключает системное мышление - и человек не копает глубже, интересно, да? :)

среда, 22 марта 2017 г.

Python joblib и GIL: ретроспектива после сессии дебага

Есть такая отличная библиотечка для параллелльного запуска одной функции с разными параметрами в параллельных потоках - joblib.

Сегодня я столкнулся с тем, что некоторые библиотечки питона могут быть зависимы от логики GIL, из-за чего при параллельном выполнении метода вы можете получать System Error: broken pipe, хотя тот же код в один поток будет работать.

В моем случае все осложнялось ещё и тем, что код, который падал, был внутри фикстуры для автоматических тестов, запускаемых с pytest. И без pytest проблема не воспроизводилась, а дебажить работу функции, запускаемой через joblib.Parallel внутри pytest фикстуры это то ещё удовольствие.

Самое печальное это то, что несколько часов поиска в Интернете не давали ничего вменяемого, как будто с этой проблемой никто не сталкивался раньше, поэтому я решил написать эту статью, чтобы, если кто-то ещё столкнется с подобной проблемой, она могла вас навести на правильное решение.

Решение кроется в использовании альтернативного метода для параллельного запуска кода - multi-threading, который, конечно же, зависит от GIL, но и ваш код не падает, как в случае с multiprocessing.

Чтобы намекнуть joblib использовать multi-threading, вам необходимо указать параметр backend=“threading”, вот так:
from joblib import Parallel, delayed

results = Parallel(n_jobs=200, backend='threading')(
                delayed(your_function)(i, parameter2)
                for i in xrange(10000))
Здесь results будет содержать список возвращаемых функцией your_function значений, your_function - функция, которую мы запустим в 200 тредов, i и parameter2 - параметры, которые будут переданы в качестве аргументов функции your_function (они не обязательные, просто как пример). Значение n_jobs определяет количество тредов, которое будет создано для запуска функции, backend='threading' сообщает интерпретатору что надо создавать именно треды, а не отдельные процессы.

Подробнее об этой библиотечке и этом параметре можно почитать здесь: http://pythonhosted.org/joblib/generated/joblib.Parallel.html

вторник, 7 февраля 2017 г.

Подборка материалов для подготовки к QA Interview (QA, Automation & Python, Linux & Networks)

Всем привет,

как и многие технические специалисты и менеджеры, я проходил и проводил множество технических интервью на позицию QA Engineer / QA Automation Engineer / Software Engineer In Testing и пр., каждая компания называет это по-своему.

Сегодня решил выложить свою подборку ссылок на интересные статьи, позволяющих быстро (за несколько дней) освежить в памяти то, что может пригодиться для прохождения технического собеседования на позицию QA Engineer / QA Automation Engineer.

Когда я сам готовился к прохождению технического интервью, мне помогали похожие статьи (например, эта и эта), но эти статьи были преимущественно ориентированны на разработчиков, поэтому я надеюсь что данная статья будет полезна многим QA инженерам, как пригодилась бы мне раньше :)

Темы, которые надо выучить, чтобы просто не выглядеть неучем (и не только не выглядеть, но и не быть им):