BLA
BLA (Blind LLM Agents) is the open-source Blue Defense MCP and CLI built to protect software artifacts against automated AI reverse-engineering workflows.
翻譯準備中
Local AI assistant for code security audits: tree-sitter/AST tools, secrets, OSV dependencies, and a quantized LLM as Auditor and Architect that finds vulnerabilities and proposes validated Auto-Fix diffs (Python, JS/TS, Go). OWASP Top 10 reports.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
SecureCode AI — мультиагентный ассистент для аудита безопасности кода на Python, JavaScript/TypeScript и Go. Система находит уязвимости, классифицирует их по CWE и OWASP Top 10 и предлагает исправления в виде diff, которые перед публикацией проходят автоматическую проверку. Модель может работать локально, поэтому исходный код не покидает машину разработчика. Английская версия — в README.en.md.檢視完整 README ↗
Русский | English
SecureCode AI — мультиагентный ассистент для аудита безопасности кода на Python, JavaScript/TypeScript и Go. Система находит уязвимости, классифицирует их по CWE и OWASP Top 10 и предлагает исправления в виде diff, которые перед публикацией проходят автоматическую проверку. Модель может работать локально, поэтому исходный код не покидает машину разработчика.
Сайт проекта · Итоговый отчёт · Эксперименты · Notebook · Релизы
https://github.com/user-attachments/assets/ada9aef9-aae1-4235-a82d-4bab4dc0852b
Английская версия — в README.en.md.
ast и tree-sitter: детерминированные правила для 35 CWE,
поиск захардкоженных секретов, проверка зависимостей pip, npm и Go по базе OSV.git apply --check), проходит синтаксическую проверку и повторное сканирование. Git-ревизия (точный commit)
│
┌─────────────┴─────────────┐
▼ ▼
детерминированные сканеры Поиск (LLM)
└─────────────┬─────────────┘
▼
граф доказательств (EvidenceGraph)
│
▼
Аудитор → Скептик → решение по находке
│
▼
Архитектор: diff + проверка
│
▼
отчёт: CWE, OWASP Top 10, исправления
| Агент | Задача |
|---|---|
| Поиск | Исследует код независимо от сканеров и предлагает кандидатов в уязвимости |
| Аудитор | Проверяет кандидата: достигают ли недоверенные данные опасной операции через границу доверия |
| Скептик | Пытается опровергнуть вывод Аудитора: ищет санитизацию, безопасный API, недостижимый путь |
| Архитектор | Пишет минимальное исправление подтверждённой находки; патч проверяется до попадания в отчёт |
Проверка утверждений опирается на открытые методики Anthropic и Cloudflare. Подробное описание: архитектура, модель угроз.
Демонстрация на уязвимом примере в Docker:
python deploy/docker/quickstart.py --demo
С локальной моделью (требуются uv и
Ollama; модель qwen2.5-coder:7b-instruct-q4_K_M, около 4.7 ГБ,
загружается автоматически):
python deploy/docker/quickstart.py --demo --provider local
Отчёты сохраняются в output/demo-report/. Прогон всех инструментов с сохранёнными
выводами: notebooks/securecode_demo.ipynb.
Требования: Git 2.44 или новее, CPython 3.12–3.14, uv 0.12.0. Docker нужен только для образов, Ollama — только для локальной модели. Локальная модель Qwen 2.5 Coder 7B Q4_K_M занимает около 4,7 ГБ на диске и требует 6–8 ГБ свободной видеопамяти или, без GPU, около 8 ГБ ОЗУ (медленнее); для DeepSeek GPU не нужен.
git clone https://github.com/shorinversion/securecode-ai.git
cd securecode-ai
uv sync --locked
uv run securecode --version
uv run securecode analyze path/to/repo --output report.md
Команда выполняет полный конвейер: сканеры, Поиск, Аудитор, Скептик, решение по каждой находке и исправления Архитектора.
Для --provider openai-compatible адрес, модель и ключ задаются в окружении или .env:
SECURECODE_MODEL_BASE_URL=https://api.openai.com/v1
SECURECODE_MODEL=gpt-4o-mini
SECURECODE_MODEL_API_KEY=...
Подходит любой сервис с этим API по публичному HTTPS-адресу: OpenAI, OpenRouter, Groq,
Together, корпоративный шлюз. Необязательные настройки: SECURECODE_MODEL_PRICE_INPUT и
SECURECODE_MODEL_PRICE_OUTPUT (USD за миллион токенов; без них стоимость в отчёте «не
известна», а --max-cost-usd не действует, прогон ограничен 20 млн токенов),
SECURECODE_MODEL_CONTEXT_TOKENS и SECURECODE_MODEL_MAX_OUTPUT_TOKENS (по умолчанию 128000
и 16384), SECURECODE_MODEL_REASONING_EFFORT. Все роли, включая Архитектора, обращаются к
этому адресу; секреты маскируются так же, как для DeepSeek. Условия хранения данных у
выбранного сервиса SecureCode не проверяет: выбирая его, вы соглашаетесь отправить туда
код проверяемого репозитория (решение D-118).
| Параметр | Назначение |
|---|---|
--provider deepseek|openai-compatible|local | Модель: DeepSeek (DEEPSEEK_API_KEY в окружении или .env), любой HTTPS-сервис с API OpenAI Chat Completions (см. ниже) или локальная через Ollama |
--format markdown|html|json|sarif | Формат отчёта |
--output FILE | Записать отчёт в файл |
--output-dir DIR | Сохранить за один прогон report.md, report.html, report.json и report.sarif |
--base REV | Проверить только файлы, изменённые с точки слияния REV и HEAD (для pull request: --base origin/main; нужен полный git fetch, не shallow). Потоки данных в неизменённые файлы и не изменившиеся манифесты зависимостей не перепроверяются; область указана в JSON (scope), SARIF (properties.securecode_scope) и строкой «Область» отчёта (D-124) |
--baseline FILE | Файл известных находок (securecode-baseline/v1, см. «Baseline для CI»): подтверждённая слабость из него показывается как известная и не даёт код 2 |
--write-baseline FILE | Записать в новый файл все подтверждённые слабости этого прогона |
--patch-dir DIR | Сохранить проверенные исправления в .diff-файлы: по файлу на исправление (каждый diff применяется к исходному файлу) и patch-<файл>.diff со всеми исправлениями файла, если их несколько |
--mode full|verify | full: Поиск читает все окна репозитория; verify: только окна, которые помещаются в бюджет модели, сначала со сработками сканеров (n из m окон — в отчёте и в JSON mode). По умолчанию verify для --provider local, иначе full. Размер окна локальной модели: SECURECODE_LOCAL_CONTEXT_TOKENS (2048..32768, по умолчанию 8192), SECURECODE_LOCAL_MAX_OUTPUT_TOKENS (256..4096, 2048), SECURECODE_LOCAL_CONTEXT_BYTES (до 8× окна, 65536), SECURECODE_LOCAL_REPOSITORY_CALLS (1..64, 16), SECURECODE_LOCAL_TIMEOUT_SECONDS (1..30, 30); Ollama надо запускать с OLLAMA_CONTEXT_LENGTH не меньше окна (D-123) |
--no-fix | Не запрашивать исправления. Без флага Архитектор предлагает до 10 исправлений за прогон, по одному на группу слабости: два ключа в одном файле — два исправления, они строятся одно поверх другого |
--max-cost-usd N | Лимит расходов на API за прогон (по умолчанию 1.0); перед каждым запросом резервируется его максимальная стоимость, около $0.04, поэтому лимит ниже $0.20 может остановить проверку |
Коды возврата: 0 — подтверждённых уязвимостей нет и все обязательные этапы выполнены;
2 — есть хотя бы одна подтверждённая уязвимость (этот код важнее незавершённых этапов);
3 — подтверждённых уязвимостей нет, но часть этапов или кандидатов осталась без решения;
4 — ошибка аргументов, нет ключа, Git старше 2.44, в ревизии нет поддерживаемых
исходников или файл отчёта уже существует. Если прогон остановился без отчёта,
сообщение называет код причины (например, GIT_COMMAND_FAILED). Checkout другого
пользователя (CI-контейнер, смонтированный том) проверяется, если Git ему доверяет:
git config --global --add safe.directory <путь>.
В JSON проверенные исправления лежат в patch_refs и validation_refs находки, в SARIF —
в стандартном поле fixes. Сканер и модель могут подтвердить одну и ту же слабость:
такие находки получают общий weakness_group в JSON и partialFingerprints
(securecodeWeakness/v2) в SARIF; считать и показывать их нужно один раз. Группа — CWE в
одном файле, а для захардкоженных секретов — ещё и строка: два ключа в разных строках
файла — две слабости.
Блок decision у находки показывает, кто её подтвердил: authority MODEL_REVIEW
(согласие Аудитора и Скептика) или DETERMINISTIC_DETECTOR (детектор секретов, D-117),
причину reason, вердикты обеих моделей и число обращений к ним (auditor_calls,
skeptic_attempts).
При коде 3 отчёт перечисляет кандидатов без окончательного решения с причиной для
каждого; это не «уязвимостей нет», а места для ручной проверки. В JSON они лежат в
undecided_candidates с теми же счётчиками и признаком retries_exhausted; кандидаты,
которые уже покрыты подтверждённой находкой того же места, — в covered_candidates с
полем covered_by. Стоимость прогона — в model_cost (usd, known).
Если этап не завершён, отчёт называет причину кодом; в JSON она лежит в
coverage_diagnostics (deterministic.reasons: OBSTACLE:…, SCAN_INCOMPLETE,
RECEIPT_NOT_SUCCEEDED:…, BINDING_MISMATCH:…, EXCEPTION:…; в них нет путей и
исходников). SECURECODE_TRACE=файл дописывает JSONL-трассу этапов (статусы,
типы исключений, длительности; без исходников, промптов и путей),
SECURECODE_SCAN_BUDGET_SECONDS (60..600) задаёт время на все процессы сканеров: по
умолчанию две секунды на файл, но не меньше минуты и не больше десяти (D-121).
securecode analyze . --base origin/main --format json --output report.json
securecode publish github --report report.json --repo OWNER/NAME --pr 7
Команда publish github ведёт один сводный комментарий (обновляется на месте по маркеру) и
по одному комментарию к строке на каждую новую подтверждённую слабость; если проверенное
исправление — один hunk рядом со строкой, в комментарии есть блок suggestion. Известные
по baseline находки в комментарии не выносятся, только в счётчик сводки. Токен берётся из
переменной --token-env (по умолчанию GITHUB_TOKEN) и никогда не печатается; --dry-run
показывает тела комментариев без сети и токена. GitHub отклоняет комментарий к строке вне
diff pull request: такая находка остаётся в сводке. Готовый шаблон для Actions (с
--base, SARIF и комментариями; все действия закреплены по SHA) —
integrations/github/action.yml, пример — в integrations/github/README.md (D-126).
Команда без изменений кода принимает существующие слабости и ловит только новые:
securecode analyze . --write-baseline .securecode-baseline.json # один раз, файл — в репозиторий
securecode analyze . --baseline .securecode-baseline.json # в CI: код 2 только для новой слабости
Файл — JSON {"schema": "securecode-baseline/v1", "created", "head_sha", "weaknesses": [...]};
запись — weakness_group (из отчёта), cwe_id, path, reason (accepted или
false_positive) и expires (дата или null). Ключ — weakness_group: он не зависит от
правок вокруг, кроме захардкоженных секретов, где в группу входит строка (D-125). Известные
находки остаются в JSON с полем suppressed, получают suppressions в SARIF и уходят в
свёрнутый раздел «Известные находки (N)»; outcome ядра не меняется, итог для CI — в
effective_outcome. Запись с истёкшим expires игнорируется (предупреждение в сводке).
Если всё подтверждённое известно, прогон даёт 0 при полном покрытии и без нерешённых
кандидатов, иначе 3. Неверный файл — код 4 до первого вызова модели.
Пример фрагмента отчёта:
| № | Уязвимость | OWASP Top 10 | Критичность | Место | Исправление |
| 1 | CWE-89 SQL Injection | A03:2021 Injection | HIGH | app.py:5 | исправление проверено |
uv run python -I demo/p917_real_local_demo.py --repository path/to/repo --output out --provider deepseek --open-pr
Архитектор коммитит проверенное исправление в ветку securecode/fix-… и открывает pull
request через GitHub CLI (gh). Для GitLab тот же флаг открывает merge request через
glab: платформа определяется по адресу origin, явно её задаёт --forge gitlab.
Исправления из securecode analyze --patch-dir DIR применяются вручную:
git apply DIR/01-….diff, затем glab mr create или gh pr create. Пример:
shorinversion/securecode-demo-app#1.
securecode scan — блокирующая проверка для CI на заранее одобренном хосте: привязка к
точному commit, одобренные профили модели и политики исходящих данных. Развёртывание
control plane, worker и интеграций с GitHub и GitLab описано в
docs/OPERATIONS.md.
Демонстрация Аудитор → Архитектор на локальной Qwen 2.5 Coder 7B Q4_K_M и на DeepSeek: SQL-инъекция (CWE-89, A03:2021) найдена, исправление с параметризованным запросом прошло проверку. Квитанции: Qwen, DeepSeek.
Реальные репозитории на Python, JavaScript и Go: подтверждены SQL-инъекции, внедрение команд, открытый редирект, обход пути, отсутствие проверки подписи JWT; ложное срабатывание CSRF отклонено. Стоимость прогона — $0.003–0.011.
OWASP Benchmark for Python (1230 кейсов, 14 категорий; оценка TPR − FPR, 1 — идеально). В конфигурации SecureCode решение принимается согласием трёх проверок: Поиск (модель без подсказок), Аудитор (модель проверяет находки сканеров) и вторая модель; CWE попадает в отчёт, если её назвали минимум две из трёх (голоса сравниваются по семействам CWE из иерархии MITRE); слабое хеширование решает детерминированное правило. «Только модель» — та же модель без сканеров, для сравнения:
| Конфигурация | Оценка | Precision |
|---|---|---|
| SecureCode: согласие трёх проверок (gpt-oss-120b, Luna) | 0,84 | 89,2% |
| SecureCode: согласие трёх проверок (gpt-oss-120b, DeepSeek Flash) | 0,82 | 85,9% |
| SecureCode: сканеры + проверка gpt-oss-120b | 0,78 | 89,0% |
| SecureCode: сканеры + проверка DeepSeek Flash | 0,50 | 59,7% |
| SecureCode: только сканеры | 0,21 | 70,4% |
| Только модель: gpt-oss-120b | 0,80 | 85,6% |
| Только модель: DeepSeek Flash | 0,39 | 53,8% |
| Bandit 1.9.4 | 0,16 | 87,8% |
| Semgrep 1.177.0 | 0,16 | 57,8% |
CVEfixes (3000 файлов: пары «до и после исправления CVE», 118 CWE; отложенная выборка 1200 файлов):
| Конфигурация | Recall | Разница с Semgrep, п. п. (95% ДИ) |
|---|---|---|
| SecureCode: сканеры ∪ GPT-5.6 Luna | 50,5% | +16,2 [+11,3; +21,0] |
| Сканеры SecureCode ∪ Semgrep | 43,8% | +9,5 [+7,2; +11,8] |
| Semgrep 1.177.0 | 34,3% | — |
| SecureCode: только сканеры | 25,2% | −9,2 [−13,3; −5,0] |
Методика, Bandit, gosec, ESLint, модели с открытыми весами, разбивка по языкам и ограничения: отчёт об экспериментах. Датасеты: CVEfixes, OWASP Benchmark for Python.
| Язык | Файлы | Анализ |
|---|---|---|
| Python | .py, .pyi | AST и CST, таблица символов, 35 CWE |
| JavaScript / TypeScript | .js, .mjs, .cjs, .jsx, .ts, .tsx | CST, таблица символов, 35 CWE |
| Go | .go | CST, таблица символов, 35 CWE |
| Все | манифесты pip, npm, Go; любые файлы | уязвимые зависимости (OSV), секреты |
Детерминированные правила покрывают инъекции (CWE-78, 79, 89, 90, 94), обход пути (22), SSRF (918), отсутствие аутентификации и авторизации (306, 862), небезопасную десериализацию (502), слабую криптографию (327, 338), захардкоженные учётные данные (798), ReDoS (1333) и другие. Агенты не ограничены этим списком: модель может сообщить о любой из 139 CWE таблицы соответствия OWASP Top 10 2021.
INDETERMINATE, а не «уязвимостей нет»."sk-" + "..."), детектор не распознаёт, и такой
код уходит в модель как есть. Найденный детектором секрет (CWE-798) подтверждается
самим детектором: модели видят только маркер и не решают, настоящий ли это ключ.Подробнее: классификация данных, защита от prompt injection.
uv sync --locked --group quality
uv run --locked python -I scripts/quality.py
scripts/quality.py запускает форматирование и линтер Ruff, mypy для Linux и Windows,
unit- и интеграционные тесты с порогом покрытия ядра 80%. CI повторяет проверки на
Python 3.12, 3.13 и 3.14 и дополнительно сканирует секреты и зависимости.
| Путь | Содержимое |
|---|---|
apps/cli/ | CLI securecode |
apps/server/, apps/worker/ | control plane и worker для CI |
packages/contracts/ | версионированные контракты и JSON Schema |
packages/core/ | доменная логика: граф доказательств, политика, отчёты, исправления |
packages/adapters/ | Git, tree-sitter, модели, песочница, отчёты, SCM |
demo/ | демонстрации и уязвимые примеры |
notebooks/ | демонстрационный notebook |
report/ | итоговый отчёт и эксперименты |
tests/ | unit-, контрактные и интеграционные тесты |
docs/ | архитектура, решения, безопасность, эксплуатация |
Лицензия не выбрана; все права принадлежат автору. Учебный корпус в
evaluation/development/ распространяется под CC0-1.0.