Обмен технологиями

Вопрос 50 на внешнем собеседовании (Какие общие меры безопасности на внешнем интерфейсе могут предотвратить атаки CSRF?)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Вставьте сюда описание изображения
Чтобы предотвратить атаки межсайтовой подделки запросов (CSRF), во внешней разработке можно принять следующие общие меры безопасности:

1. Используйте токен CSRF

Это один из наиболее часто используемых защитных механизмов.

  • Создать токен: после входа пользователя в систему сервер генерирует случайный непредсказуемый токен CSRF и сохраняет его на стороне сервера. В то же время он отправляется клиенту через заголовок Set-Cookie и сохраняется в файле cookie пользователя.

  • Формировать встроенный токен: в каждую HTML-форму, нуждающуюся в защите, добавьте скрытое поле (<input type="hidden">), его значением является токен CSRF, считанный из файла cookie.

  • Верифитокен : Когда форма будет отправлена, серверная часть получит данные формы и токен в файле cookie (из-за политики одного и того же источника браузер автоматически отправит файл cookie). Серверная сторона проверяет, соответствует ли токен в форме токену, хранящемуся на стороне сервера или в сеансе. Если они не соответствуют друг другу, запрос отклоняется.

2. Проверьте HTTP-реферер и заголовок источника.

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

  • Проверить реферер : проверьте поле Referer в заголовке HTTP-запроса, чтобы убедиться, что запрос инициируется с ожидаемого имени домена. Однако следует отметить, что этот метод имеет ограничения. Например, при запросе на переход с HTTPS на HTTP реферер не будет отправлен.

  • Проверьте заголовок источника: аналогично Referer, заголовок Origin предоставляет информацию об источнике запроса, но отправляется только при использовании XMLHttpRequest или Fetch API.

3. Используйте атрибут SameSite Cookie.

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

  • SameSite=Лакс: файлы cookie отправляются только в запросах одного и того же сайта, что частично защищает от CSRF.
  • SameSite=Строгий: файлы cookie отправляются только в пределах одного и того же сайта и в пределах одной и той же страницы навигации, что обеспечивает более надежную защиту, но может повлиять на некоторые ожидаемые межподдоменные функции.
  • SameSite=Нет: необходимо использовать с атрибутом Secure для файлов cookie, которые должны быть межсайтовыми, чтобы адаптироваться к требованиям современных браузеров.

4. Проверка заголовка пользовательского запроса

Добавьте собственный HTTP-заголовок в запрос AJAX (например,X-Requested-With: XMLHttpRequest ), а затем проверьте наличие и значение этого заголовка на стороне сервера. Поскольку JavaScript может свободно устанавливать заголовок XMLHttpRequest, а обычная отправка формы — нет, это позволяет различать запросы, инициированные сценариями.

Пример кода (реализация токена CSRF):

Серверная часть (псевдокод):

// 生成并设置Token
function generateCsrfToken() {
    return crypto.randomBytes(32).toString('hex');
}

app.post('/login', (req, res) => {
    const token = generateCsrfToken();
    res.cookie('csrfToken', token, { httpOnly: true, secure: true, sameSite: 'strict' });
    // 存储token到session或其他存储机制
});

app.post('/submitForm', (req, res) => {
    if (req.body.csrfToken === req.cookies.csrfToken) {
        // 请求合法,处理逻辑...
    } else {
        // CSRF攻击检测,拒绝请求
        res.status(403).send('Forbidden');
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Интерфейсный HTML:

<form action="/submitForm" method="POST">
    <!-- 其他表单字段... -->
    <input type="hidden" name="csrfToken" value="{{csrfToken}}">
    <button type="submit">Submit</button>
</form>
  • 1
  • 2
  • 3
  • 4
  • 5

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