Объясните принцип CSRF-атак и защиту от них.java-74

CSRF (Cross-Site Request Forgery) — это тип атаки, при которой злоумышленник заставляет жертву выполнить нежелательные действия на веб-сайте, где пользователь аутентифицирован. Например, это может быть перевод денег, изменение пароля или отправка сообщения. CSRF-атаки возможны, если веб-приложение не проверяет источник запросов.

Принцип работы CSRF-атак

1. Как работает CSRF?

  • Пользователь входит на сайт (например, банк) и получает аутентификационную cookie.
  • Злоумышленник создает вредоносную страницу или письмо с формой или JavaScript-кодом, который отправляет запрос на сайт банка от имени пользователя.
  • Если пользователь посещает эту страницу или открывает письмо, браузер автоматически отправляет запрос с аутентификационной cookie.
  • Сервер банка обрабатывает запрос, считая его легитимным, и выполняет действие (например, перевод денег).

2. Пример CSRF-атаки

Предположим, есть форма перевода денег на сайте банка:

<form action="https://bank.com/transfer" method="POST">
    <input type="hidden" name="amount" value="1000">
    <input type="hidden" name="toAccount" value="attackerAccount">
    <input type="submit" value="Transfer Money">
</form>

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

<form action="https://bank.com/transfer" method="POST" id="csrfForm">
    <input type="hidden" name="amount" value="1000">
    <input type="hidden" name="toAccount" value="attackerAccount">
</form>
<script>document.getElementById('csrfForm').submit();</script>

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

Защита от CSRF-атак

1. Использование CSRF-токенов

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

Пример реализации CSRF-токена в Spring Boot:

import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;

@RestController
public class CsrfController {

    @PostMapping("/transfer")
    public String transferMoney(@RequestParam String amount, 
                               @RequestParam String toAccount, 
                               HttpServletRequest request) {
        // Проверка CSRF-токена
        String csrfToken = request.getParameter("csrfToken");
        String sessionToken = (String) request.getSession().getAttribute("csrfToken");

        if (csrfToken == null || !csrfToken.equals(sessionToken)) {
            return "CSRF attack detected!";
        }

        // Логика перевода денег
        return "Money transferred successfully!";
    }
}

2. SameSite Cookies

Атрибут SameSite для cookies предотвращает отправку cookies в запросах, инициированных с других сайтов. Это эффективно защищает от CSRF-атак.

Пример настройки SameSite в Spring Boot:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;

@Configuration
public class CookieConfig {

    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
        serializer.setSameSite("Strict");
        return serializer;
    }
}

3. Проверка заголовка Origin/Referer

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

Пример проверки заголовка Origin:

import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;

@RestController
public class CsrfController {

    @PostMapping("/transfer")
    public String transferMoney(@RequestParam String amount, 
                               @RequestParam String toAccount, 
                               HttpServletRequest request) {
        String origin = request.getHeader("Origin");
        if (!"https://bank.com".equals(origin)) {
            return "CSRF attack detected!";
        }

        // Логика перевода денег
        return "Money transferred successfully!";
    }
}

4. Двойная отправка cookies

Метод заключается в отправке CSRF-токена как в форме, так и в cookie. Сервер проверяет, что значения токена в форме и cookie совпадают.

Пример реализации:

import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@RestController
public class CsrfController {

    @PostMapping("/transfer")
    public String transferMoney(@RequestParam String amount, 
                               @RequestParam String toAccount, 
                               @RequestParam String csrfToken,
                               HttpServletRequest request, 
                               HttpServletResponse response) {
        String cookieToken = request.getCookies()[0].getValue();

        if (csrfToken == null || !csrfToken.equals(cookieToken)) {
            return "CSRF attack detected!";
        }

        // Логика перевода денег
        return "Money transferred successfully!";
    }
}

5. Использование CAPTCHA

CAPTCHA может быть использована для подтверждения действий пользователя, что усложняет проведение CSRF-атак.

Пример интеграции CAPTCHA:

import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@RestController
public class CaptchaController {

    private final String SECRET_KEY = "your_secret_key";
    private final String VERIFY_URL = "https://www.google.com/recaptcha/api/siteverify";

    @PostMapping("/transfer")
    public String transferMoney(@RequestParam String amount, 
                               @RequestParam String toAccount, 
                               @RequestParam String captchaResponse) {
        RestTemplate restTemplate = new RestTemplate();
        String url = VERIFY_URL + "?secret=" + SECRET_KEY + "&response=" + captchaResponse;
        String response = restTemplate.postForObject(url, null, String.class);

        if (!response.contains("\"success\": true")) {
            return "CAPTCHA verification failed!";
        }

        // Логика перевода денег
        return "Money transferred successfully!";
    }
}

Резюмируем

  • CSRF-атаки эксплуатируют доверие сервера к аутентификационным cookies, отправляемым браузером автоматически.
  • Основные методы защиты:
    • Использование CSRF-токенов.
    • Настройка SameSite cookies.
    • Проверка заголовков Origin/Referer.
    • Метод двойной отправки cookies.
    • Использование CAPTCHA.
  • Внедрение этих методов в ваше приложение значительно снижает риск CSRF-атак и повышает безопасность пользовательских данных.

Следование этим рекомендациям поможет вам защитить ваше приложение от CSRF-атак и обеспечить безопасность пользователей.