В рубрику "Оборудование и технологии" | К списку рубрик | К списку авторов | К списку публикаций
Если бы не существовало никакой модели безопасности, приложения могли бы выполнять зловредные действия для юзера или Web-ресурсов. Со временем многие Web-технологии пришли к единой модели безопасности, известной нам как Same-Origin Policy.
По сути, SOP запрещает сторонним скриптам обращаться к текущей вкладке в браузере путем проверки источника – Origin. Источник определяется комбинацией протокола, URL и порта:
http:// + www.example.com + :80
Любой скрипт, пришедший с другого Origin, не имеет права доступа к содержимому документа и его cookies. Зачем это нужно? Представим себе ситуацию, когда скрипт из любой вкладки браузера имеет доступ к другим вкладкам. В такой ситуации, один раз посетив любой нехороший сайт, мы отдадим все свои cookies, а также все содержимое наших вкладок – переписки, картинки и т.д. Чтобы такого не происходило, все современные браузеры используют SOP1.
Шло время, технологии развивались, и у разработчиков все чаще возникала необходимость все-таки обращаться к другим Origins. Простейший пример – когда сайт использует api, а api находится на другом домене и, соответственно, другом источнике. По умолчанию браузер не разрешит такой запрос. И тут на помощь приходит CORS2.
С помощью CORS (Cross-Origin Resource Sharing) ресурс может указать, какие сторонние источники (Origins) могут получить доступ к его содержимому. Оковы пали! Наконец-то разработчики могут пересылать всякое интересное между разными ресурсами.
В стандарте CORS описывается довольно много заголовков для разных целей, наиболее интересными для нас выглядят эти три:
Указывает, какие домены имеют доступ к ресурсам текущего домена. То есть если домен нужен-доступ.рф хочет иметь доступ к домену можем-дать-доступ.рф, разработчики последнего могут использовать этот заголовок.
Указывает, будет ли браузер посылать cookie вместе с запросом. Куки будут отсылаться только если значение заголовка равно True.
Указывает, какие HTTP-методы (GET, PUT, DELETE и т.д.) могут быть использованы для доступа к ресурсу.
Представим, что мы отправили вот такой запрос к сайту:
GET /api/userinfo
Host: vlopate.com
Origin: vlopate.com
И в ответ получаем, среди прочего, следующее:
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Это значит, что vlopate.com отдает информацию о пользователе любому сайту. Все, что осталось, – это создать зловредный ресурс, разместить на нем код, обращающийся к vlopate.com/api/user-info, и заманить на этот ресурс пользователей. Все их данные принадлежат нам.
Допустим, разработчики все-таки задумались о безопасности и настроили CORS, на запрос:
GET /api/userinfo
Host: vlopate.com
Origin: vlopate.com
Мы получаем:
HTTP/1.0 200 OK
Access-Control-Allow-Origin: vlopate.com
Access-Control-Allow-Credentials: true
И все, казалось бы, хорошо, но разработчик был с похмелья и в настройках бэкенда указал проверку следующим образом:
if ($_SERVER['HTTP_HOST'] == '*vlopate.com'):
access.granted()
else:
raise.404()
Видите звездочку (*)? Это означает, что мы можем зарегистрировать домен mi_ne_vlopate.com, и на наш запрос:
GET /api/userinfo
Host: vlopate.com
Origin: mi_ne_vlopate.com
получим утвердительный ответ:
HTTP/1.0 200 OK
Access-Control-Allow-Origin: mi_ne_vlopate.com
Access-Control-Allow-Credentials: true
Через неделю разработчики отошли от празднования релиза и поправили код на:
if ($_SERVER['HTTP_HOST'] == '*.vlopate.com'):
access.granted()
else:
raise.404()
тем самым разрешив доступ только поддоменам.
Придется идти на крайние меры. Поиск дает результат – найдена XSS на поддомене kartofel.vlopate.com. А это значит, при ее эксплуатации мы все равно получим доступ к данным vlopate.com, так как наш скрипт работает от имени его поддомена.
При разработке внимательно относитесь к настройке CORS, также внимательно относитесь к нему при аудитах или багбаунти.
Для проверки могут помочь готовые скрипты из github: https://github.com/chenjj/CORScanner https://github.com/RUB-NDS/CORStest
Отмечу, что всецело на них полагаться не стоит, важные и интересные случаи лучше дополнительно проверить руками.
Успехов!
Опубликовано: Журнал "Information Security/ Информационная безопасность" #4, 2019