Главная  /  Статьи  /  Security

Аудит безопасности кода с Vibe Codex

Хороший security-аудит — это не «найди дыру», а «покажи, какие классы проблем здесь физически невозможны».

Вес security-проблемы редко зависит от изощрённости — обычно это банальный SQL-конкатенат, незахешированный токен или забытый http.Get(userInput). Vibe Codex эти паттерны ловит охотно, потому что они шаблонны. Сложные дыры остаются человеку — но и тут ассистент сужает поиск.

Команда одной строкой

$ vibe-codex audit security --scope ./src
[opus] Сканирую 12 380 файлов...
[opus] 7 находок (3 high, 2 medium, 2 low):

HIGH    src/billing/PaymentController.java:42
        SQL injection — конкатенация userId в строку запроса
HIGH    src/api/upload.py:88
        SSRF: requests.get(user_url) без allowlist
HIGH    src/auth/Token.go:112
        SHA-1 для подписи токенов
MEDIUM  src/admin/views.py:25
        IDOR: нет проверки ownership на GET /docs/<id>
MEDIUM  src/integration/SapClient.kt:74
        XML без отключения внешних entities — XXE
LOW     src/utils/RandomId.java:14
        java.util.Random для генерации session-id
LOW     .env.example
        выглядит как реальный ключ, проверьте

Паттерн №1. SQL-инъекции

Самая частая находка. Vibe Codex ищет конкатенации строк в SQL, использование %s с user input, format-функции в запросах.

// найдено
@GetMapping("/payments/{userId}")
public List<Payment> list(@PathVariable String userId) {
    return jdbcTemplate.query(
        "SELECT * FROM payments WHERE user_id = " + userId,
        rowMapper
    );
}

// предлагаемая правка
return jdbcTemplate.query(
    "SELECT * FROM payments WHERE user_id = ?",
    rowMapper,
    Long.parseLong(userId)
);

Паттерн №2. SSRF

Бэкенд, который ходит по URL из тела запроса, — это SSRF, пока не доказано обратное. Ассистент подсветит и предложит allowlist или whitelist + SOCKS-прокси.

# найдено
@app.post('/preview')
def preview(url: str):
    return requests.get(url).text

# предлагаемая правка
ALLOWED_DOMAINS = {'images.acme.ru', 'cdn.acme.ru'}

@app.post('/preview')
def preview(url: str):
    parsed = urlparse(url)
    if parsed.scheme not in {'https'}:
        raise HTTPException(400, 'https only')
    if parsed.hostname not in ALLOWED_DOMAINS:
        raise HTTPException(400, 'domain not allowed')
    return requests.get(url, timeout=5,
                        allow_redirects=False).text

Паттерн №3. Криптография «своими руками»

SHA-1, MD5, плоский XOR «для скрытия токена», CBC без HMAC, Math.random() для session-id. Список классики, который не меняется десять лет.

// найдено
func signToken(uid string) string {
    h := sha1.New()
    h.Write([]byte(uid + secret))
    return hex.EncodeToString(h.Sum(nil))
}

// предлагаемая правка
func signToken(uid string) string {
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write([]byte(uid))
    return hex.EncodeToString(mac.Sum(nil))
}
«Хороший аудитор не объясняет, почему MD5 это плохо. Он показывает, на что заменить».

Паттерн №4. IDOR

Endpoint GET /documents/<id> без проверки, что текущий пользователь владеет документом. Очень частый баг в API-фастлайт.

# найдено
def get_doc(doc_id: int, user: User):
    return Document.objects.get(id=doc_id)

# предлагаемая правка
def get_doc(doc_id: int, user: User):
    return Document.objects.get(id=doc_id, owner_id=user.id)
# или сначала запрос, потом явная проверка:
#   if doc.owner_id != user.id: raise PermissionDenied

Паттерн №5. Секреты в репозитории

Ассистент ищет «похожее на ключ»: 32-символьные строки в hex, JWT-формат, AWS-форматы, BEGIN PRIVATE KEY. Не «помогает выйти на GitHub Secret Scanning», а сам сообщает в pre-commit, что в diff поехал ключ.

$ git commit -m "wip"
[pre-commit] vibe-codex security:
  WARN  config/local.yml:14 looks like an API key
        (entropy 4.8, format /^[A-Za-z0-9]{40}$/)
[pre-commit] commit aborted. fix or pass --allow-secret

Что ассистент НЕ делает

Ритуал недели

Раз в неделю — на pre-merge или в Friday-deploy gate — запускается полный аудит:

vibe-codex audit security --since=7d --format=sarif > audit.sarif

Результат — SARIF, который кладётся в GitHub Code Scanning или импортируется в Defect Dojo. Дальше — обычный workflow безопасников: тикеты, фиксы, ревалидация.

Граница ответственности

Vibe Codex — это инструмент, который снимает с инженера 80% рутины security-обзора. 20% остаются человеку: бизнес-логические уязвимости (race на бонусы, fraud-сценарии), архитектурные ошибки (доверие между сервисами), human-эксплойты. Их не находит ни один скан, потому что они не паттерны.

Идея простая: пусть рутина уходит ассистенту, а интересное — людям. Так и работает security в нормальной команде.

Готов попробовать?

brew tap xrouter-chat/tap && brew install vibe-codex — и за 30 секунд ты в деле.

Поставить Vibe Codex →