CSRF проверки

CSRF (Cross-Site Request Forgery) является одной из распространённых уязвимостей в веб-приложениях. Она позволяет атакующему отправить поддельный запрос от имени пользователя, не осознающего того, что его данные были использованы. Важно обеспечить, чтобы тесты, автоматизируемые с помощью Playwright, учитывали проверку CSRF, поскольку веб-приложения, активно использующие токены CSRF для защиты от таких атак, требуют особого подхода.

Что такое CSRF и зачем это важно

CSRF использует доверие веб-приложения к браузеру пользователя. Когда пользователь авторизован в приложении и его сессия всё ещё активна, атакующий может заставить браузер пользователя отправить нежелательный запрос на сервер. Например, это может быть запрос на изменение пароля, перевод денег или удаление аккаунта, при этом жертва не осознает происходящее.

Токены CSRF служат для предотвращения таких атак. Это случайно генерируемые строки, которые сервер включает в каждый запрос, направленный к нему от клиента. Приложение ожидает, что токен из заголовков запроса будет соответствовать тому, что был прислан ранее.

Применение Playwright для тестирования CSRF

Для эффективного тестирования защиты от CSRF в Playwright, необходимо взаимодействовать с токенами CSRF, которые веб-приложение передает в разных частях системы: в cookies, в заголовках, в теле запросов или в скрытых полях форм. Рассмотрим основные подходы к этому.

  1. Сбор токенов CSRF с сервера

    В большинстве случаев веб-приложения отправляют CSRF токен в виде метки в заголовке или в теле HTML-страницы. Например, в HTML-разметке можно увидеть следующий элемент:

    <input type="hidden" name="csrf_token" value="abcdef123456">

    В таком случае, чтобы протестировать защиту от CSRF, необходимо извлечь этот токен и использовать его для последующих запросов.

    В Playwright это делается следующим образом:

    const page = await browser.newPage();
    await page.goto('https://example.com/login');
    
    const csrfToken = await page.locator('input[name="csrf_token"]').getAttribute('value');

    Получив токен, его можно будет использовать в запросах для проверки защиты от CSRF.

  2. Отправка защищённых запросов

    Чтобы отправить запрос, который будет защищён CSRF токеном, необходимо убедиться, что в запрос включён правильный токен. Рассмотрим пример отправки POST-запроса через Playwright с правильным токеном:

    await page.fill('input[name="username"]', 'testUser');
    await page.fill('input[name="password"]', 'password123');
    await page.fill('input[name="csrf_token"]', csrfToken);
    await page.click('button[type="submit"]');

    В этом примере токен CSRF передается в форму перед отправкой, что позволяет приложению безопасно обработать запрос.

  3. Проверка работы защиты

    Важным шагом является проверка того, что приложение правильно отклоняет запросы с неправильным или отсутствующим токеном CSRF. Для этого можно попытаться отправить запрос без токена или с поддельным токеном, ожидая отказ от сервера. Пример проверки:

    await page.goto('https://example.com/change-password');
    const incorrectToken = 'invalidToken123';
    
    await page.fill('input[name="currentPassword"]', 'oldPassword');
    await page.fill('input[name="newPassword"]', 'newPassword');
    await page.fill('input[name="csrf_token"]', incorrectToken);
    await page.click('button[type="submit"]');
    
    const errorMessage = await page.locator('.error-message').textContent();
    expect(errorMessage).toContain('Invalid CSRF token');

    В этом случае, если приложение корректно настроено, оно отклонит запрос с поддельным токеном и выведет ошибку.

  4. Использование cookies для хранения CSRF токенов

    В некоторых случаях CSRF токены могут храниться в cookies. Это требует особого подхода к извлечению токенов и отправке их в запросах.

    Пример получения CSRF токена из cookies в Playwright:

    const cookies = await page.context().cookies('https://example.com');
    const csrfTokenCookie = cookies.find(cookie => cookie.name === 'csrf_token');
    const csrfToken = csrfTokenCookie ? csrfTokenCookie.value : null;

    Получив токен, можно использовать его для отправки запросов, как было показано выше.

Тестирование защиты от CSRF в различных сценариях

  1. Тестирование с валидным токеном

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

  2. Тестирование с невалидным или отсутствующим токеном

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

  3. Тестирование с подделанным токеном

    Здесь тестировщик создает случайный или фальшивый токен и пытается отправить запрос с ним. Сервер должен отклонить такие попытки, предотвращая возможные атаки.

Отчётность и диагностика ошибок CSRF

Правильная настройка обработки ошибок также важна для успешного тестирования. Если CSRF защита не сработает должным образом, приложение должно выдавать информативные сообщения об ошибках, чтобы разработчик мог быстро диагностировать и исправить проблему.

Пример обработки ошибки при отсутствии CSRF токена:

const errorMessage = await page.locator('.error-message').textContent();
expect(errorMessage).toContain('CSRF token is missing or invalid');

Такие сообщения помогут ускорить процесс отладки и избежать ошибок при защите приложения.

Заключение

CSRF защита является важным элементом безопасности веб-приложений. В процессе тестирования с использованием Playwright важно учитывать сценарии, где токен CSRF передаётся через различные механизмы — в заголовках, теле запроса или cookies. Корректная проверка всех возможных вариантов использования токенов CSRF позволяет удостовериться в правильной работе защиты и предотвратить атаки.