---
title: "Слепая зона безопасности"
type: "ai-smell"
slug: "security-blind-spot"
url: "http://localhost:3000/ru/ai-smells/security-blind-spot.md"
category: "Корректность"
description: "ИИ-ассистенты выдают функциональный код, который молча опускает средства защиты, которые человек добавил бы по привычке — валидацию ввода, авторизацию, кодирование вывода, работу с секретами — потому что \"оно компилируется и возвращает 200\" выглядит как готово."
---
# Слепая зона безопасности

> ИИ-ассистенты выдают функциональный код, который молча опускает средства защиты, которые человек добавил бы по привычке — валидацию ввода, авторизацию, кодирование вывода, работу с секретами — потому что "оно компилируется и возвращает 200" выглядит как готово.

## Signs and Symptoms

Ревьюер замечает слепую зону безопасности, когда код _работает_ на счастливом пути, но средства защиты, которые человек с настроем на безопасность добавляет рефлекторно, попросту отсутствуют. Модель демонстрирует функцию, а не защиту. Характерные признаки:

* **Запросы / команды, собранные конкатенацией строк** вместо параметризованных (точки внедрения SQL/команд/LDAP).
* **Пользовательский ввод попадает в вывод без кодирования** (отражённый/хранимый XSS) или в `fs`/`child_process`/`fetch` без белого списка (обход пути, SSRF).
* **Эндпоинт аутентифицирует, но никогда не авторизует** — он проверяет, _кто вы_, но никогда — _можете ли вы трогать эту запись_ (IDOR / нарушенная авторизация на уровне объектов).
* **Захардкоженные секреты** — ключи API, токены, пароли БД встроены "чтобы оно запустилось".
* **Средства защиты, отсутствующие по упущению**: нет CSRF-токена, нет заголовков безопасности, нет ограничения частоты, слабая/устаревшая криптография (MD5, SHA-1, `Math.random()` для токенов).
* **Театр комментариев**: комментарий `// validate input` или `// TODO: add auth` сидит там, где должна быть настоящая проверка — OX обнаружила избыточные комментарии в 90–100% ИИ-кода, часто заменяющие отсутствующую логику.

```js
// Сгенерированный ИИ обработчик Express — выглядит завершённым, выпускает три дыры
app.get("/api/orders/:id", authMiddleware, async (req, res) => {
  const apiKey = "sk_live_8f3b2a91c7d44e0f";            // 1. захардкоженный секрет
  const order = await db.query(
    `SELECT * FROM orders WHERE id = ${req.params.id}`   // 2. SQL-инъекция
  );
  res.send(`<h1>Order for ${order.customerName}</h1>`);  // 3. отражённый XSS
  // примечание: authMiddleware подтверждает вход, но никогда не проверяет order.userId === req.user.id (IDOR)
});

```

Четыре различные уязвимости, ноль падающих тестов — запах в том, чего _нет_.

## Reasons for the Problem

**Почему модели это порождают**

* **Цель обучения — правдоподобие, а не безопасность.** Предсказание следующего токена оптимизирует _наиболее распространённый_ способ написания кода, а публичные корпуса насыщены сниппетами учебного уровня — с конкатенированными запросами и без авторизации. OX Security отмечает, что модели "по умолчанию выбирают небезопасные подходы, поскольку они чаще всего встречаются в обучающих данных". Carnegie Mellon обнаружил, что 61% ИИ-сниппетов _работают_, но лишь \~10,5% проходят ревью безопасности.
* **"Готово" определяется счастливым путём.** LLM оптимизирует так, чтобы видимый запрос завершился успехом. Средства защиты не дают положительного сигнала при быстром запуске, поэтому их отбрасывают — то, что OX называет _"небезопасностью по неведению": функциональный код с отсутствующими мерами защиты, потому что никто из участников не знал, что требовалось._
* **Нет контекста репозитория.** Модель не видит вашу вспомогательную функцию `authorize()`, вашу схему валидации или ваш менеджер секретов, поэтому встраивает литеральный ключ или пропускает проверку вместо переиспользования существующего средства защиты.
* **Подхалимство + скорость.** Она возвращает буквально то, что вы попросили ("добавь эндпоинт заказа"), а не модель угроз вокруг него, а узкие места вроде ревью и моделирования угроз — это ровно то, что устраняет разработка на скорости ИИ — ключевой вывод OX в том, что именно _скорость_, а не частота дефектов на строку, отправляет уязвимый код в продакшен.
* **Устаревание из-за порога обучения.** Модели хватаются за криптографические и библиотечные паттерны, которые были приемлемы годы назад (MD5, SHA-1, устаревшие опции TLS, старые потоки аутентификации).

**Почему это вредит**

* **Прямая эксплуатируемость.** Независимые исследования, цитируемые OX: \~62% сгенерированного ИИ кода попадает в продакшен с уязвимостью; 86% провалили защиту от XSS (CSET/Georgetown); CodeRabbit измерил в 2,74 раза больше XSS, чем в человеческом коде; Tenzai обнаружил, что 0 из 15 построенных ИИ приложений выставляют заголовки безопасности или защиту от CSRF; Escape.tech нашёл 400+ открытых секретов в 5600 vibe-приложениях.
* **Невидимо для тестов и для читателей.** Отсутствующая проверка авторизации не имеет падающего теста и диффа, на который можно указать, поэтому она беспрепятственно проходит ревью — а объём вывода ИИ означает, что ревью не масштабируется, чтобы её поймать.
* **Накапливающийся техдолг.** Данные GitClear (рефакторинг упал с 25% до <10% изменённых строк, копипаста выросла и теперь превышает перемещённые строки, дублированные блоки выросли примерно в 8 раз) означают, что один и тот же небезопасный паттерн клонируется по кодовой базе, умножая радиус поражения любой отдельной слепой зоны.

## Treatment

**Тактики ревью и промптинга**

* **Назовите модель угроз в промпте.** "Напиши этот эндпоинт, считая, что `id` контролируется злоумышленником; обеспечь авторизацию на уровне объектов, параметризуй все запросы, кодируй весь вывод и читай секреты из `process.env`". Указание противника переворачивает поведение по умолчанию.
* **Принуждайте к переиспользованию существующих средств защиты.** "Используй нашу вспомогательную функцию `authorize(user, 'order', id)` и валидатор `orderSchema` — не пиши новую валидацию". Это прямо противодействует причине отсутствия контекста репозитория (и смежному запаху _Duplicate Code_).
* **Заставьте модель запускать инструменты.** Требуйте, чтобы она запускала `semgrep --config p/owasp-top-ten`, `gitleaks detect`, `npm audit` и ваш конфиг `eslint-plugin-security`, затем исправляла то, что они отметят, прежде чем объявлять о готовности.
* **Явно спрашивайте об отрицательных моментах.** "Перечисли вопросы аутентификации, авторизации, валидации ввода, кодирования вывода и работы с секретами для этого обработчика и покажи, где каждый из них обеспечен". Пробел в этом списке _и есть_ ошибка.
* **Моделируйте угрозы для диффа, а не для строки.** Опасные дыры — это упущения, поэтому проводите ревью, спрашивая "какое средство защиты должно быть здесь и которого нет?", а не выискивая плохие строки.

**Рефакторинг** — параметризуйте запрос (убивает инъекцию), кодируйте вывод (убивает XSS), добавьте проверку авторизации на уровне объектов (убивает IDOR) и _извлеките_ встроенный секрет в конфигурацию:

```js
// ПОСЛЕ
app.get("/api/orders/:id",
  authMiddleware,
  validate(orderParamsSchema),                    // валидация ввода
  async (req, res) => {
    const order = await db.query(
      "SELECT * FROM orders WHERE id = $1", [req.params.id]   // параметризовано
    );
    if (!order || order.userId !== req.user.id) {            // авторизация на уровне объектов
      return res.sendStatus(404);
    }
    res.json({ customerName: order.customerName });          // структурированный вывод, автоматически кодируется
  }
);
// секрет: process.env.STRIPE_API_KEY, загружается один раз при старте, никогда не встраивается

```

Там, где запах распространился клонированием, исправьте его один раз и **Extract Function** (Извлеките функцию) средства защиты (`requireOrderOwnership`, `escapeHtml`), чтобы каждое место вызова разделяло одну проверенную реализацию вместо N копий.

## Detected by

- **Gitleaks** `hardcoded secrets / generic-api-key` (https://github.com/gitleaks/gitleaks)
- **Semgrep** `p/owasp-top-ten (e.g. sql-injection, xss, dangerous formatstring sinks)` (https://semgrep.dev/p/owasp-top-ten)
- **GitHub CodeQL** `js/sql-injection, js/xss, js/hardcoded-credentials, js/path-injection` (https://codeql.github.com/codeql-query-help/javascript/)
- **eslint-plugin-security** `detect-non-literal-fs-filename, detect-child-process, detect-eval-with-expression, detect-object-injection` (https://github.com/eslint-community/eslint-plugin-security)
- **Bandit (Python)** `B105 hardcoded_password_string, B608 hardcoded_sql_expressions, B324 weak hashlib` (https://bandit.readthedocs.io/en/latest/plugins/index.html)
- **SonarQube / SonarSource** `Security Hotspots & Vulnerability rules (injection, weak cryptography, hardcoded credentials)` (https://rules.sonarsource.com/javascript/type/Vulnerability/)
- **npm audit / OWASP Dependency-Check** `known-vulnerable dependency detection` (https://owasp.org/www-project-dependency-check/)
