Веб-интерфейсы промышленного оборудования часто доверяют клиенту больше, чем следует — роль администратора можно получить, просто подставив число 64 в запрос, если бэкенд не проверяет права.
Анализ с просмотра исходного кода страницы. Это стандартный подход при исследовании неизвестных систем. Первый сигнал тревоги отсутствие метатега viewport. Что значит, интерфейс не адаптирован под мобильные устройства. Для панели управления оборудованием это странно, но объяснимо: такие системы обычно открывают с рабочего места оператора, а не с телефона.
Почему фронтенд не хранит пароли по умолчанию
Я искал захардкоженные учётные данные в файлах авторизации. Их нет. Это правильный подход разработчиков: пароли не должны попадать в клиентский код. Аутентификация уходит на сервер через запрос POST /login. Фронтенд лишь формирует JSON с полями username, password, rememberme и отправляет его.
Сервер отвечает объектом пользователя с полем role. Числовые значения ролей зашиты в константы:
- 1 — публичный доступ
- 2 — только чтение
- 4 — пользователь
- 8 — пользователь уровня 2
- 16 — пользователь уровня 3
- 32 — администратор модуля
- 64 — полный администратор системы
Эта схема называется RBAC — role-based access control. Права доступа определяются ролью, а роль присваивается пользователю на сервере. Проблема возникает, когда сервер доверяет значению роли, которое пришёл клиент.
Как работает проверка прав в AngularJS приложении
Я изучил файл authorization.js. В нём реализована защита маршрутов через $routeChangeStart. Перед загрузкой страницы система проверяет, есть ли у пользователя нужные права:
if (!Auth.authorize(nextAccess)) {
$location.url('/login');
}
Функция authorize выполняет побитовую операцию & между требуемым уровнем доступа и ролью пользователя. Если результат ненулевой — доступ разрешён. Это эффективный способ хранения нескольких прав в одном числе, но он работает только если роль пользователя нельзя подделать.
Вот где появляется риск. Метод Auth.getUsers принимает роль как аргумент:
Auth.getUsers($scope.currentUser.role, success, error)
Если бэкенд не перепроверяет эту роль на своей стороне, любой пользователь может запросить список администраторов, подставив 64 вместо своей реальной роли.
Что такое инъекция роли и как её проверить
После загрузки Angular-приложения выполнил команду:
angular.element(document.body).injector().get('Auth').getUsers(64, console.log, console.error)
Сервер вернул массив с пользователем admin и ролью 64. Это подтверждает: endpoint /getusers доступен, а проверка прав либо отсутствует, либо реализована некорректно.
Теперь можно пойти дальше. Следующий логичный шаг — попытка создать нового администратора:
angular.element(document.body).injector().get('Auth').addUser(
64, "testadmin", 64, {}, "Test123!", console.log, console.error
)
Если запрос пройдёт, у вас появится учётная запись с полными правами. Это уже не теоретическая уязвимость, а реальный компромисс системы.
[√] Проверьте доступность /getusers без авторизации — это покажет, открыт ли API для анонимных запросов
[√] Попробуйте вызвать /adduser с ролью 64 — успешный ответ означает возможность создания администратора
[ ] Протестируйте /changeuserpassword для смены пароля существующего пользователя — это вектор захвата аккаунта
[√] Изучите ответ сервера на некорректные запросы — сообщения об ошибках иногда раскрывают внутреннюю логику
Почему эти проверки важны: каждая из них тестирует отдельный слой защиты. Если хотя бы один запрос срабатывает без должной авторизации, система уязвима.
Как отличить уязвимость от ожидаемого поведения
Не каждый доступный API — это дыра. Некоторые системы сознательно разрешают определённые операции анонимным пользователям. Ключевой вопрос: соответствует ли поведение документации и ожидаемой модели безопасности?
Система предназначена для внутренней сети, доступ к ней контролируется брандмауэром, а API требует аутентификации через cookie. В этом случае открытый /getusers может быть допустим. Интерфейс доступен из интернета, а роль передаётся в теле запроса без дополнительной проверки. Это уже критическая ошибка архитектуры.
Как проверить контекст? Посмотрите, как система обрабатывает неавторизованные запросы. Если /login возвращает 400 Bad Request при неправильном формате, но /getusers молча принимает любые данные — это признак непоследовательной реализации защиты.
Какие ещё векторы атаки стоит проверить
Я составил список endpointов, которые часто становятся точками входа при слабой авторизации:
/adduser— создание пользователя/deleteuser— удаление учётной записи/modifyuser— изменение прав или пароля/getCertFiles— получение списка сертификатов/copyCert— копирование сертификата на сервер/setWSConfiguration— изменение конфигурации веб-сервера
Каждый из них может быть опасен, если не проверяет права вызывающего пользователя. Особенно критичны операции с сертификатами и конфигурацией: через них можно отключить HTTPS, перенаправить трафик или вызвать перезапуск сервиса.
Я заметил в коде интервал обновления данных каждые 10 секунд:
setInterval(function() { $scope.getUsers(); }, 10000);
Это удобно для анализа: запросы идут регулярно, их легко перехватить прокси-инструментом вроде Burp Suite или OWASP ZAP.
Как задокументировать найденные проблемы
Рекомендую фиксировать каждый шаг исследования. Это поможет воспроизвести уязвимость и оценить её критичность. Минимальный набор данных для отчёта:
- точный URL endpoint’а
- метод запроса (GET/POST)
- заголовки, которые отправляются по умолчанию
- тело запроса в формате, который принимает сервер
- ответ сервера с кодом состояния и содержимым
- условия, при которых уязвимость проявляется
Не указывайте в отчёте точные пароли или токены, если они попали в логи. Замените их на плейсхолдеры вроде ***. Это стандартная практика при описании инцидентов.
Где читатель может проверить сам: откройте инструменты разработчика в браузере, перейдите на вкладку Network, выполните действие в интерфейсе и изучите отправленный запрос. Сравните его с тем, что описано в документации к системе.
Почему защита на уровне фронтенда не работает
Разработчики дублируют проверки прав и в браузере, и на сервере, считая это надёжной защитой. На практике клиентские проверки легко обходятся. Достаточно отправить запрос напрямую, минуя интерфейс.
Безопасность должна строиться на принципе «не доверяй клиенту». Сервер обязан самостоятельно определять права пользователя на основе сессии, токена или другого механизма, который нельзя подделать со стороны клиента. Передача роли в теле запроса — это антипаттерн, который превращает систему в мишень.
Интересный момент: в коде есть разделение на AuthUserRole и AuthAccessLevel. Первое — конкретная роль пользователя, второе — битовая маска прав. Это грамотная архитектура, но она не спасает, если сервер использует значение из клиента вместо собственного расчёта.
Как проверить систему без риска её повредить
Советую начинать с пассивного анализа. Изучите код, документацию, сетевые запросы. Только потом переходите к активным тестам, и то — в изолированной среде.
[√] Создайте резервную копию конфигурации перед любыми изменениями — это позволит откатиться при сбое
[ ] Используйте тестовые учётные записи вместо реальных — так вы не заблокируете легитимных пользователей
[√] Фиксируйте все запросы и ответы — это поможет восстановить ход исследования при возникновении проблем
[ ] Ограничьте тесты по времени — длительные сессии могут создать нагрузку на систему
Почему эти меры важны: они снижают вероятность случайного отказа сервиса. Даже если вы тестируете уязвимость, цель — найти проблему, а не создать инцидент.
Что делать после обнаружения уязвимости
Лучше сразу ограничить доступ к интерфейсу, если он открыт в интернет. Затем — уведомить ответственных за систему. Если вы проводите аудит по договору, следуйте согласованному процессу отчётности.
Не публикуйте детали уязвимости до того, как разработчик выпустит исправление. Это стандартная практика ответственного раскрытия. Даже если система кажется изолированной, информация может попасть к злоумышленникам.
Где можно проверить актуальность проблемы: обратитесь к вендору оборудования с указанием версии. Запросите информацию о известных уязвимостях и доступных обновлениях.
Какие инструменты помогут в исследовании
Браузерные DevTools достаточно для анализа сетевых запросов и выполнения команд в консоли AngularJS. Для более глубокого тестирования подойдёт Burp Suite Community или OWASP ZAP.
Если нужно автоматизировать проверку, напишите простой скрипт на Python с использованием requests. Пример запроса:
import requests
r = requests.post('http://target/getusers', json={'role': 64})
print(r.status_code, r.json())
Не забывайте указывать заголовок Content-Type: application/json, если сервер его ожидает. Иначе получите 400 Bad Request, как было в начале исследования.
#информационнаябезопасность #вебинтерфейс #angularjs #rbac #аудитбезопасности #промышленныесистемы #api