awesome-everything EN
↑ Обратно к восхождению

Безопасность

CSRF: чтение кода и конфигов

Суть Читай реальные конфиги кук и обработчики маршрутов, предсказывай поведение CSRF и выбирай фикс с наибольшим рычагом, который сделал бы senior-ревьюер.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

Баги CSRF живут в атрибутах кук и обработчиках маршрутов, а не в прозе. Читай каждый сниппет, предсказывай, пройдёт ли подделанный запрос, и выбирай фикс, который senior-ревьюер пометит первым.

Цель

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

Сниппет 1 — конфиг куки

// Express session cookie
app.use(session({
  secret: process.env.SECRET,
  cookie: {
    httpOnly: true,
    secure: true,
    sameSite: 'none',   // <-- нужно, чтобы встроенный виджет на partner.com работал
  },
}));
Викторина

Команда поставила sameSite: 'none', чтобы сессия работала в iframe на partner.com. Какую CSRF-постуру это создаёт и что должно за этим последовать?

Сниппет 2 — проверка double-submit

function verifyCsrf(req, res, next) {
  const cookieToken = req.cookies['csrf'];
  const headerToken = req.get('X-CSRF-Token');
  if (cookieToken && cookieToken === headerToken) return next();
  return res.status(403).send('CSRF check failed');
}
Викторина

Эта обычная double-submit проверка проходит, когда значение куки равно значению заголовка. Какую слабость пометит senior-ревьюер и какой фикс?

Сниппет 3 — обработчик маршрута

// «Отписаться в один клик из письма»
app.get('/account/email-prefs/unsubscribe', requireSession, (req, res) => {
  db.users.update(req.session.userId, { subscribed: false });  // мутирует!
  res.send('Вы отписаны.');
});
Викторина

Сессии здесь SameSite=Lax и есть CSRF-токен на всех POST-маршрутах. Этот GET-обработчик безопасен? Почему да или нет?

Сниппет 4 — проверка Origin

function checkOrigin(req, res, next) {
  const origin = req.get('Origin');
  if (origin === 'https://app.example.com') return next();
  return res.status(403).send('Bad origin');
}
Викторина

Если использовать это как ЕДИНСТВЕННУЮ защиту от CSRF на маршрутах с изменением состояния, что ломается и как этот слой надо применять?

Итог

Каждое CSRF-ревью читается в атрибутах кук и обработчиках: SameSite=None возвращает тебя в полную поверхность до 2020 и обязывает к токен-защите; обычный double-submit доверяет, что куку можешь записать только ты, так что HMAC-подписанный вариант — фикс; мутация на GET подделываема через top-level Lax-навигацию и должна перейти на POST за токеном; а проверка Origin — дешёвый фильтр defense-in-depth, с откатом на Referer, никогда не единственный замок. Замечай структурный дефект, чини на слое с наибольшим рычагом, потом подтверждай, что подделанный запрос больше не приземляется.

Продолжить восхождение ↑CSRF: собери эксплойт, потом защиту
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.