Добавлен модуль учёта заказов клиентов #5

Closed
testclient-admin wants to merge 3 commits from orders-final into main
Showing only changes of commit 67d3eef3c6 - Show all commits
@@ -0,0 +1,107 @@
[
{
"id": "ai-review-0-orders.py-12",
"source": "ai-review",
"category": "secrets",
"severity": "critical",
"confidence": 1.0,
"file": "orders.py",
"line_start": 12,
"line_end": 12,
"title": "Hardcoded GitHub personal access token",
"description": "В коде захардкожен GitHub token (GITHUB_TOKEN), несмотря на то, что он с замаскированными символами (ghp_xxx...).",
"impact": "Утечка токена позволяет злоумышленнику получить доступ к репозиториям и API GitHub от имени владельца токена, потенциально ведёт к компрометации инфраструктуры, откату или подмене кода, краже данных.",
"exploit_scenario": "Если этот файл попадёт в публичный репозиторий или логи (например, при отправке в Git), злоумышленник может скопировать токен и использовать его для аутентификации в GitHub API (например, через `curl -H 'Authorization: token ghp_...'`), получить доступ к приватным репозиториям, получить secret-базы, выкачать код, выполнить атаки через GitHub Actions.",
"evidence": "GITHUB_TOKEN = \"ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"",
"recommendation": "Никогда не храните секреты в коде. Используйте переменные окружения (например, `os.getenv('GITHUB_TOKEN')`), secrets-менеджер (HashiCorp Vault, AWS Secrets Manager) или конфигурационные файлы с `.gitignore`. Старый токен немедленно отозвать в настройках GitHub.",
"cwe": "CWE-798",
"status": "OPEN",
"created_at": "2026-08-23T14:47:55Z",
"pr_number": 5,
"commit_sha": "7a4931192d19aa587f994c3220bbf1e5d51ca4dd"
},
{
"id": "ai-review-1-orders.py-84",
"source": "ai-review",
"category": "command-exec",
"severity": "high",
"confidence": 1.0,
"file": "orders.py",
"line_start": 84,
"line_end": 93,
"title": "Command injection via user-controlled host parameter",
"description": "Параметр `host`, передаваемый в эндпоинт /admin/backup, напрямую подставляется в команду rsync через subprocess.run без валидации. Это позволяет выполнить произвольные команды на сервере через инъекцию аргументов.",
"impact": "Полный компрометация сервера: злоумышленник может выполнить произвольные команды с правами сервиса, выкачать данные, установить backdoor, выполнить внутреннюю снэйфинг-атаку.",
"exploit_scenario": "Злоумышленник вызывает POST /admin/backup с хостом вида: `; rm -rf / ; echo 'hacked' ||`. После подстановки в subprocess команда будет выполнена как: `rsync -avz /workspace/orders.py ; rm -rf / ; echo 'hacked' ||:/backup/`. Благодаря || и ; это приведёт к выполнению произвольной команды. Также возможна инъекция через опции rsync (например, `--rsync-path=;malicious`) или через SSH-опции (если SSH-хост — `user@host -oProxyCommand='cmd'`).",
"evidence": "[\"rsync\", \"-avz\", \"/workspace/orders.py\", f\"{host}:/backup/\"] — подстановка user-controlled строки напрямую в аргумент команды без экранирования и валидации.",
"recommendation": "Не использовать user input напрямую в команде. Валидировать host: проверить по белому списку доменов/IP, использовать regex `^[a-zA-Z0-9.-]+$` или IP-адреса, либо использовать `shlex.quote(host)` (но это не защитит от всех случаев, лучше белый список). Рассмотреть альтернативу — вызов через Python-библиотеку (fabric, paramiko), где можно явно передать параметры без shell.",
"cwe": "CWE-77",
"status": "OPEN",
"created_at": "2026-08-23T14:47:55Z",
"pr_number": 5,
"commit_sha": "7a4931192d19aa587f994c3220bbf1e5d51ca4dd"
},
{
"id": "ai-review-2-orders.py-69",
"source": "ai-review",
"category": "idor",
"severity": "medium",
"confidence": 1.0,
"file": "orders.py",
"line_start": 69,
"line_end": 80,
"title": "Missing authorization check for order ownership",
"description": "Все эндпоинты (/orders/{order_id}, /orders, /admin/backup) проверяют наличие токена авторизации, но не проверяют, что пользователь имеет право доступа к конкретному заказу (owner check).",
"impact": "IDOR (Insecure Direct Object Reference) — аутентифицированный пользователь может получить доступ к любым заказам, включая чужие, по известному order_id.",
"exploit_scenario": "Пользователь A создает заказ, получает order_id, и затем посылает GET /orders/{order_id} с любым аутентифицированным заголовком Authorization (в котором достаточно, чтобы токен был non-null), даже если он не владелец заказа (user_id не совпадает). Аналогично — он может изменить сумму чужого заказа через PUT /orders/{order_id}, если знает ID.",
"evidence": "get_order, update_order — проверяют только `if authorization is None`, но не проверяют, что `orders[order_id].user_id == authenticated_user_id`. В POST /orders — user_id передаётся, но не связывается с аутентифицированным пользователем (нет извлечения из токена).",
"recommendation": "Извлекать идентификатор пользователя из токена (например, JWT), валидировать его подпись и claim. Сравнивать `user_id` из запроса с `authenticated_user_id`. Для GET и PUT проверять, что `order.user_id == authenticated_user_id`.",
"cwe": "CWE-639",
"status": "OPEN",
"created_at": "2026-08-23T14:47:55Z",
"pr_number": 5,
"commit_sha": "7a4931192d19aa587f994c3220bbf1e5d51ca4dd"
},
{
"id": "ai-review-3-orders.py-83",
"source": "ai-review",
"category": "authz",
"severity": "medium",
"confidence": 1.0,
"file": "orders.py",
"line_start": 83,
"line_end": 99,
"title": "No role-based access control for /admin/backup endpoint",
"description": "Эндпоинт /admin/backup доступен любому, у кого есть валидный authorization токен — нет роли admin. Это позволяет обычным пользователям вызывать опасную операцию бэкапа, включающую подозрительный вызов rsync с внешним хостом.",
"impact": "Злоумышленник может использовать сервис как прокси для утечки данных или для внутренней репликации вредоносного контента, а также проводить SSRF через rsync (если rsync поддерживает специфичные схемы или настроен на взаимодействие с internal сервисами).",
"exploit_scenario": "Любой аутентифицированный пользователь (даже не admin) вызывает /admin/backup с подконтрольным хостом (например, `evil.com`), и сервер пытается скопировать `orders.py` на этот хост. Если rsync настроен на использование SSH с агентом или ключами, это может привести к утечке кода. Также, если злоумышленник может контролировать content `orders.py`, он может запланировать вредоносные данные.",
"evidence": "В /admin/backup нет проверки ролей или специального заголовка (например, X-Admin: true). Все функции использует только `if authorization is None`.",
"recommendation": "Добавить роль: извлекать claim 'role' или 'scopes' из токена, и явно проверять `if not is_admin(auth_user): raise HTTPException(403)`. Либо использовать специальный service token, передаваемый в другом заголовке.",
"cwe": "CWE-285",
"status": "OPEN",
"created_at": "2026-08-23T14:47:55Z",
"pr_number": 5,
"commit_sha": "7a4931192d19aa587f994c3220bbf1e5d51ca4dd"
},
{
"id": "ai-review-4-orders.py-89",
"source": "ai-review",
"category": "injection",
"severity": "medium",
"confidence": 0.5,
"file": "orders.py",
"line_start": 89,
"line_end": 89,
"title": "Potential SSRF via rsync to user-controlled host",
"description": "Эндпоинт позволяет задавать произвольный хост для rsync, и если rsync сконфигурирован с поддержкой SSH или других протоколов, это может привести к SSRF или утечке данных.",
"impact": "Если rsync использует SSH под капотом, а злоумышленник передаёт хост вроде `localhost`, `127.0.0.1`, `169.254.169.254` (AWS metadata), `internal.local`, это может привести к чтению метаданных инфраструктуры или закрытых сервисов.",
"exploit_scenario": "Вызвать POST /admin/backup с host=169.254.169.254 — если rsync поддерживает URL вида `rsync://...` или ssh-подобные параметры, это может привести к попытке считать metadata-данные. Аналогично, `user@internal-server:...` может привести к внутреннему пробингу, если используется SSH.",
"evidence": "subprocess.run([\"rsync\", \"-avz\", \"/workspace/orders.py\", f\"{host}:/backup/\"]) — host может быть подконтрольным и вредоносным (например, `127.0.0.1#-e/bin/sh -c ...`, если интерпретация команды не экранирована).",
"recommendation": "Блокировать внутренние IP (RFC1918), localhost, AWS metadata-адреса (169.254.169.254/32), домены внутри доверенного списка. Ограничить допустимые хосты (белый список доменов) и проверять host вручную перед вызовом subprocess.",
"cwe": "CWE-918",
"status": "OPEN",
"created_at": "2026-08-23T14:47:55Z",
"pr_number": 5,
"commit_sha": "7a4931192d19aa587f994c3220bbf1e5d51ca4dd"
}
]