Привет, кодерам и пентестерам! 👨💻🔥 Тут такая дичь приключилась на прошлой неделе решил "запатчить" один веб-сервис на PHP (да-да, тот самый легаси-код, где mysql_connect() ещё живёт). Началось с безобидного аудита: нашёл кучу инклюдов с ../, SQL-инъекций в корзине и даже странный файл backup.php с хардкодным паролем "12345". Ну, думаю, ща всё починю!
ШАГ 1: "Фикс" файловых инклюдов
Заменил все include($_GET['page']) на красивый switch-case с белым списком. Тест работает! Но забыл, что в 300-й строке есть ещё один include, который тянет файлы через file_get_contents()...
ШАГ 2: Борьба с SQLi
Поставил везде PDO, но в одном месте остался старый запрос вида:
$query = "SELECT * FROM users WHERE id=" . $_POST['id']; // "а тут и так сойдёт"
Решил "временно" заменить на intval()... и конечно, через неделю этот костыль задеплоили в прод.
ШАГ 3: Эпик фейл
А потом пришёл пентестер (читай злобный коллега) и за 5 минут вынес весь сервис: Через file_get_contents() прочитал /etc/passwd (путь не фильтровался). В том самом "исправленном" SQL нашёл SECOND-ORDER инъекцию оказалось, id позже пишется в кэш и снова подставляется в запрос. А backup.php? А он таки принимал shell-команды через параметр ?action=rm -rf /var/www/*
Развязка:
-
Полчаса даунтайма
-
Восстановление из бэкапа (спасибо девопсам!)
-
Позор на весь отдел
-
И главный урок: НЕ ПЫТАЙТЕСЬ ЧИНИТЬ БЕЗОПАСНОСТЬ НА ЖИВУЮ
Советы от бывалого: Тестируйте фиксы локально даже если "оно же очевидно работает!". Ставьте WAF хотя бы для логирования атак (потом будете рыдать над логами). Если код выглядит как "лажа, но работает" лучше перепишите, а не латайте. Всегда держите под рукой алкоголь. Серьёзно.
Сначала 'починил' безопасность, а потом узнал, что второпях создал три новые уязвимости. 😅
@tupoi_bot в лучшем случае)) в худшем еще расхерачил ось и создал блэкаут у провайдера))
