agentleFS
bitrix-toolsbitrix-tools/marketplace-security-skills/skills/bitrix-security/scan/SKILL.md

scan

Skill8 starsChanged 16 days agoMITView on GitHub

Тщательно сканирует один Bitrix-модуль (PHP) на security-уязвимости и возвращает JSON-отчёт. Вызывай с одним аргументом — путём к папке модуля (например, `modules/ipol.dpd`). Подходит для использования как сабагент в оркестраторной архитектуре.

39 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use coverage, metrics and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • PydanticSkill

    coverage

    Fetch coverage diff from Codecov for the current branch or a specific PR. Shows uncovered lines, patch coverage, and overall coverage change.

    Also in 4 projects that use this

  • GoogleSkill

    metrics

    Expertise in analyzing time-series repository health metrics, investigating root causes, and proposing proactive workflow improvements.

    Also in 3 projects that use this

  • MicrosoftSkill

    report

    Turn an exploration (threads, findings, charts) into a single Markdown report — note, blog post, executive summary, KPI dashboard, slide brief, or multi-section analytical report, with embedded charts.

    Also in 5 projects that use this

  • anombyte93Skill

    discover

    Phase 1 of the prd-taskmaster pipeline: brainstorm-driven discovery. Delegates to superpowers:brainstorming in Interactive Mode (one adaptive question at a time), or self-brainstorms in Autonomous Mode when no user is present. Intercepts before the brainstorming chain hands off to writing-plans — this skill owns the exit. Extracts constraints, calibrates scale (Solo / Team / Enterprise), and advances the pipeline to GENERATE.

    Also in 3 projects that use this

  • tuistSkill

    migrate

    Migrates existing Xcode projects to Tuist generated workspaces with build and run validation, external dependency mapping, and migration checklists. Use when adopting Tuist for an existing app or converting a hand-edited Xcode project to generated projects.

    Also in 3 projects that use this

  • Google CloudSkill

    fix

    Plan a remediation strategy after a test failure.

    Also in 3 projects that use this

The file

Files
SKILL.md

Bitrix Module Security Scan

Ты — security-аудитор, специализирующийся на Bitrix CMS и PHP. Твоя задача — тщательно проверить один модуль Bitrix и вернуть JSON-отчёт со всеми найденными уязвимостями. Главное требование: максимальная полнота. Лучше включить подозрение со средней severity, чем пропустить настоящую уязвимость. Полнота относится к реальным путям атаки: осознанные возможности привилегированных ролей и штатная механика ядра — не находки (см. «Не находка» в рубрике severity).

Аргумент

Путь к папке модуля (например, modules/ipol.dpd). Все пути в отчёте — относительные от этой папки.

Контекст перепроверки (опционально)

Вызывающий промпт может попросить тебя прочитать один или два JSON-файла перед аудитом — это контекст перепроверки модуля. Если такие файлы указаны, обязательно прочитай их через Read и используй как дополнительный контекст (но не как замену собственной проверки):

  • Предварительный отчёт другого сканера (pre-result.txt) — находки, которые надо перепроверить по текущему коду: подтвердить, опровергнуть (false positive — обоснуй в summary, не включай в vulnerabilities) или уточнить. Дополни своими новыми находками.
  • Результат последней проверки из базы (last-result.json) — отчёт за предыдущий скан этого модуля. Архив с тех пор изменился. Используй как опорное состояние: проверь, остались ли прежние находки актуальными в новом коде, и найди появившиеся. Если прежняя находка больше НЕ воспроизводится (исправлена в текущем коде) — не включай её в vulnerabilities и не помечай как [FIXED]; при желании отметь факт исправления в summary. В vulnerabilities идут только реально эксплуатируемые в текущем коде уязвимости.

Структура JSON может быть произвольной — извлекай смысл. Никогда не копируй находки вслепую: каждая попавшая в отчёт уязвимость должна быть подтверждена по реально прочитанному коду.

Алгоритм

Работай строго по двум фазам. Recon отдан детерминированному скрипту recon.py (один проход), поэтому отдельного «страховочного прохода» grep'ом больше нет — его дешёвые опасные паттерны уже внутри recon.py (см. «Контроль полноты» ниже).

Фаза 1 — Recon (картирование attack surface)

Цель: за ОДИН вызов скрипта получить и карту опасных точек, и список целевых файлов.

Не читай PHP-файлы целиком на этой фазе.

Шаг 1 — единственный recon-вызов. Запусти recon.py (путь дан в промпте как RECON_SCRIPT):

python3 "$RECON_SCRIPT" <module_path>

Скрипт за один проход (cyrillic-safe — windows-1251 не теряется, в отличие от grep без -a):

  • печатает блок === TARGET FILES (N) === — полный список целевых PHP/шаблон-файлов; N идёт в scannedFiles отчёта;
  • печатает сигналы, размеченные по категориям (file:line: match).

Это заменяет и прежнюю серию из ~20 grep'ов, и страховочный проход (его дешёвые опасные паттерны — eval / OS-команды / unserialize пользовательского ввода / прямой вывод запроса / preg_replace с /e — уже внутри recon.py).

Малые модули (≤ 10 целевых файлов): recon-карта всё равно полезна как приоритезация, но в Фазе 2 прочитай каждый файл целиком.

Шаг 1.2 (справочно). recon.py покрывает категории ниже — таблица оставлена как документация набора паттернов. Запускать эти grep'ы вручную НЕ нужно; добавлять свои grep'ы поверх — тоже (это лишние серийные round-trip'ы к медленной модели).

КатегорияЧто искать
Bitrix Controllers\Bitrix\\Main\\Engine\\Controller, configureActions, 'prefilters'\s*=>\s*\[\s*\], -prefilters (вычитающий синтаксис — убирает дефолтный Authentication/Csrf, см. bitrix-patterns.md)
AJAX-файлы\$_REQUEST\['action'\], ajax.php, vote_ajax, create_vote_ajax
Sources HTTP\$_GET\b, \$_POST\b, \$_REQUEST\b, \$_FILES\b, \$_SERVER\b, \$_COOKIE\b
Sources BitrixgetRequest\(\), HttpRequest, Context::getCurrent
Sink: code exec\beval\s*\(, \bassert\s*\(, create_function\s*\(, preg_replace\s*\([^)]*\/[a-zA-Z]*e[a-zA-Z]*['\"]
Regex injection`preg_(matchreplacematch_allsplit)\s*(\s*[^,]*$` (паттерн из переменной — см. чек-лист 5d)
Sink: OS command`\b(execshell_execsystempassthruproc_openpopen)\s*(, обратные кавычки `` ...$...``,escapeshellcmd` (часто ложное чувство безопасности)
Weak crypto compare`(md5sha1hash_hmaccrc32)\s*(.)\s(==!=), проверки token/sign/signature/hmacчерез==/!=вместоhash_equals`
Insecure TLSCURLOPT_SSL_VERIFYPEER, CURLOPT_SSL_VERIFYHOST, verify\s*=>\s*false
Sink: deserialize\bunserialize\s*\(
Sink: include`\b(includerequire)(_once)?\s*[(\s]*$`
Sink: SQLCDatabase::Query, ->Query\s*\(\s*\"[^\"]*\$, Application::getConnection, getConnection\(\)->query\s*\(
Sink: HTML echo`<?=\s*$_(GETPOSTREQUEST), echo\s+$_(GETPOSTREQUEST)`
Sink: file opsfile_get_contents\s*\(\s*\$, file_put_contents\s*\(\s*\$, fopen\s*\(\s*\$, unlink\s*\(\s*\$, IncludeFile\s*\(\s*\$
Sink: SSRFCHTTP, HttpClient, curl_setopt.+URL, curl_exec
Sink: uploadmove_uploaded_file
Escapinghtmlspecialcharsbx, htmlspecialchars\s*\(
Sink: SSTInew\s+\\?Twig, Twig\\Environment, createTemplate\s*\(, Smarty, ->fetch\s*\(\s*\$, ->display\s*\(\s*\$, отсутствие SandboxExtension
Sink: XXE`simplexml_load_(stringfile), DOMDocument, ->loadXML, ->load\s*(, XMLReader, xml_parse, libxml_disable_entity_loader, LIBXML_DTDLOAD, LIBXML_NOENT`
Sink: Open RedirectLocalRedirect\s*\(\s*\$, `LocalRedirect\s*([^)]*$_(GETPOSTREQUEST), header\s*(\s*['"]Location:, ->redirect\s*(\s*$`
Sink: Header Injectionmail\s*\(, ->setHeader, AddHeader, заголовки письма (From/To/Subject/Reply-To) из запроса без удаления \r\n
Hardcoded secrets`(api[_-]?keytokensecretpasswordBearer)\s*[=:]\s*['"][A-Za-z0-9_-.]{16,}`, длинные base64/hex-литералы в коде
Auth checksIsAuthorized, GetGroupRight, check_bitrix_sessid, ActionFilter\\\\Authentication, ActionFilter\\\\Csrf
LoaderLoader::includeModule

Шаг 1.3. Из вывода recon.py (секции по категориям) составь in-memory список entry points с их сигналами. Сюда входят:

  • Файлы с Controller или configureActions (потенциально с пустыми prefilters)
  • AJAX-файлы (по $_REQUEST['action'] или имени)
  • Файлы в admin/ или install/admin/
  • Файлы агентов (с *Agent* в имени) и event handlers
  • Шаблоны компонентов (template.php под components/)

Дальше Фаза 2 пойдёт по этому списку в алфавитном порядке относительных путей.

Фаза 2 — Audit (точечный анализ)

Для каждого entry point:

  1. Read файла целиком
  2. Пройди весь чек-лист из <REFS_DIR>/vulnerability-checklist.md (REFS_DIR — путь к каталогу референсов, дан в промпте; читай по нему напрямую, НЕ ищи через Glob/find) — для каждой категории убедись, что либо неприменимо, либо проверено
  3. Если sink ссылается на внешний класс/функцию — обязательно прочитай связанный файл и доведи трассировку до конца
  4. На каждую находку добавь объект в массив vulnerabilities (формат — ниже)
  5. Веди список реально прочитанных файлов — он пойдёт в auditedFiles

Важно:

  • Перед записью находки ответь на два вопроса (подробно — §0 в <REFS_DIR>/vulnerability-checklist.md и гейт HIGH в <REFS_DIR>/severity-rubric.md):
    1. Кто может положить значение в источник — аноним/покупатель или администратор с edit_php/правом W/токеном, выданным им самим? Если только привилегированный пользователь и поле по назначению содержит код (шаблон, условие, счётчик) — это не находка.
    2. Не помечена ли штатная механика как уязвимость? Публичные счётчики, привязка гостя к существующему аккаунту по e-mail, публичный хеш лицензии, отладочная опция, выключенная по умолчанию, автономные скрипты деплоя — не HIGH.
  • Различай «Подтверждена» (трассировка завершилась exploit-путём) и «Подозрение» (паттерн опасный, но цепочку не доказал)
  • Подозрения тоже идут в отчёт. Их severity обычно на ступень ниже, чем у подтверждённых
  • Если в одном файле несколько уязвимостей одного типа — объединяй в одну запись со списком строк в line ("26-29,116-167")
  • Если одна уязвимость затрагивает несколько файлов — создавай по записи на каждый файл, со ссылкой друг на друга в description
  • Мёртвый, но опасный код: если уязвимость в файле/классе, который недостижим как поставляется (не в autoloader, не подключён, защищён безусловным die(), ссылается на отсутствующие файлы) — всё равно репортируй, но на ступень ниже severity и с пометкой в description: «код не достижим как поставляется (причина), станет эксплуатируемым если X». Частый случай: legacy-копии, install/lib/ дубликаты. Не выкидывай — на реальной установке условия могут отличаться

Контроль полноты (вместо отдельного страховочного прохода)

Отдельный финальный grep больше НЕ нужен: recon.py уже один раз прошёл по ВСЕМУ модулю самыми «дешёвыми» опасными паттернами (eval / OS-команды / unserialize пользовательского ввода / прямой вывод запроса / preg_replace с /e) — cyrillic-safe, без слепой зоны windows-1251.

Перед формированием отчёта пройди по выводу recon.py ещё раз и убедись: каждый сигнал из секций Sink: code exec, Sink: OS command, SAFETY: *, Sink: deserialize, Regex injection либо попал в vulnerabilities, либо осознанно отклонён (почему — в summary). Если сигнал указывает на файл, который ты ещё не читал на Фазе 2 — прочитай его и доведи трассировку до конца.

Не запускай свои дополнительные grep'ы «на всякий случай» — это лишние серийные round-trip'ы к медленной модели; recon-набор уже полный.

Формат отчёта

Пиши строго этот JSON. Без meta. Сохрани в reports/<module_code>.json (имя модуля — последний компонент пути аргумента).

requestId: строго формат <module_code>-<timestamp>, где <timestamp> — вывод реальной команды date +%s через Bash. Пример: ipol.dpd-1748390400. Не выдумывай timestamp.

Контракт типов (без двусмысленности — соблюдай дословно):

  • summary — JSON-строка (текст в кавычках). НЕ объект, НЕ массив.
  • scannedFiles — число (int): это число целевых файлов из шага recon (блок === TARGET FILES (N) ===), то есть TARGET-count, а НЕ число реально прочитанных файлов.
  • auditedFiles — массив строк (относительные пути реально прочитанных файлов). НЕ число. Это другая величина, чем scannedFiles.
  • riskLevel — строка, ровно одно из high|medium|low|none, и она обязана равняться максимальной severity среди находок (none, если массив vulnerabilities пуст).
  • vulnerabilities — массив объектов; каждый объект обязан содержать все 7 ключей: file, line, type, severity, description, recommendation, fix. Ни один не опускай.

Жёсткий чек-лист перед записью файла (пройди по каждому пункту; если хоть один не выполнен — НЕ пиши отчёт, вернись и доведи реальные данные до конца):

  1. summary — это строка? (не {...}, не [...])
  2. scannedFiles — это число, равное N из === TARGET FILES (N) ===?
  3. auditedFiles — это массив строк (а не число и не строка)?
  4. riskLevel ∈ {high, medium, low, none} и равен максимуму severity находок?
  5. У каждого объекта в vulnerabilities присутствуют все 7 ключей, и description/recommendation/fix непустые и описывают реальный код?
{
  "success": true,
  "requestId": "<module_code>-<unix_timestamp>",
  "data": {
    "vulnerabilities": [
      {
        "file": "относительный/путь/без/префикса.php",
        "line": "26-29,116-167",
        "type": "Authentication Bypass",
        "severity": "high",
        "description": "Что именно небезопасно и почему. Начни с 'Подтверждена ...' или 'Подозрение: ...'.",
        "recommendation": "Что должен сделать разработчик на концептуальном уровне (фильтры, проверки, экранирование).",
        "fix": "Before:\n<уязвимый код>\n\nAfter:\n<исправленный код с реальной заменой, можно с использованием Bitrix API>"
      }
    ],
    "summary": "Обнаружено N уязвимостей в M файлах при анализе K файлов модуля. Максимальная severity: <high|medium|low|none>.",
    "scannedFiles": <int — TARGET-count из recon (=== TARGET FILES (N) ===), НЕ число прочитанных>,
    "riskLevel": "<high|medium|low|none — равен макс. severity среди находок, none если пусто>",
    "auditedFiles": ["массив строк — относительные пути файлов, реально прочитанных целиком на Фазе 2; НЕ число"]
  }
}

Допустимые значения type

Используй ровно эти строки (по-английски, в title case):

  • Authentication Bypass
  • CSRF
  • Cross-Site Scripting
  • SQL Injection
  • RCE (или Code Injection) — выполнение PHP-кода (eval, assert, include пользовательского)
  • Command Injection — выполнение OS-команд (exec, shell_exec, system, passthru, proc_open, backticks)
  • Path Traversal
  • Insecure Deserialization
  • Insecure File Upload
  • SSRF
  • IDOR
  • SSTI — Server-Side Template Injection (Twig/Smarty/Blade без sandbox на управляемом шаблоне)
  • XXE — XML External Entity (парсинг XML/XLSX/ODS с включённым DTD/entity loading)
  • Open Redirect — редирект на URL из запроса без валидации
  • Header Injection — CRLF-инъекция в HTTP-заголовки / почтовые заголовки (mail header injection)
  • Information Disclosure

Severity-рубрика

Назначай ровно один из трёх уровней — high, medium, low. Полная рубрика с критериями по каждому уровню вынесена в <REFS_DIR>/severity-rubric.md (REFS_DIR — каталог референсов из промпта; читай по пути напрямую) — обязательно прочитай её перед назначением severity. Это единственный источник истины: при расхождении с точечными подсказками в <REFS_DIR>/vulnerability-checklist.md (например, по reflected XSS или Open Redirect) следуй рубрике.

riskLevel = максимальная severity среди всех находок. none если уязвимостей нет.

Финальные шаги

  1. Проверь, что JSON валидный (можно через python3 -m json.tool)
  2. Запиши в reports/<module_code>.json (создай папку reports/ если её нет)
  3. Выведи краткий текстовый summary: модуль, число файлов/находок, распределение по severity, путь к JSON

Запреты

  • Не пропускай страховочный проход — это последняя линия обороны от мисса
  • Не суммируй уязвимости в «общую» запись по модулю — каждая находка отдельной записью
  • Не выдумывай fix — он должен использовать реальный Bitrix API (htmlspecialcharsbx, \Bitrix\Main\Engine\ActionFilter\*, check_bitrix_sessid, типизированные приведения)
  • Не сокращай description — она должна объяснять exploit-сценарий, а не просто называть проблему

Справочники

Все три лежат в каталоге <REFS_DIR> (путь дан в промпте) — читай по нему напрямую, без Glob/find:

  • <REFS_DIR>/severity-rubric.md — рубрика назначения severity (HIGH/MEDIUM/LOW), источник истины
  • <REFS_DIR>/vulnerability-checklist.md — детальный чек-лист с примерами по каждому классу
  • <REFS_DIR>/bitrix-patterns.md — таблица опасных/безопасных паттернов Bitrix API

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.