flawopen.com/Teardowns/cve-2026-87913-aws-security-agent-mcp-s3-bucket-ownership
CVE-2026-87913: утечка данных AWS MCP
Предсказуемый bucket мог принять закрытый архив сканирования в чужой аккаунт. Обновите сервер до 0.2.0 и проверьте владельца.[1], [2], [4]
Представьте курьера, который проверяет, есть ли здание по адресу, но не кому оно принадлежит. Другой человек может зарегистрировать адрес первым и получить посылку. S3 должен подтверждать ожидаемого владельца при проверке и загрузке.[2], [1]
Ключевые понятия и термины
MCP-сервер- Локальная служба с инструментами для ИИ-ассистента; они работают с правами серверного процесса.[3]
Связи со стандартами
- Ссылка CWE для слабого места, описанного в этом руководстве: CWE-283 CWE-341
- OWASP GenAI 2025 — LLM06:2025 Чрезмерные полномочия агента
Анализ первопричины
MCP-сервер AWS Security Agent формирует имя bucket из ID аккаунта клиента и региона: security-agent-scans-<account-id>-<region>. AWS и сопровождающий указывают, что уязвимая версия проверяла только существование bucket, но не владение аккаунтом клиента. Имена S3 глобальны, ID аккаунтов общедоступны. Сторонняя учётная запись, первой зарегистрировавшая предсказуемое имя, могла получить закрытый архив, загруженный сервером; в нём могут быть исходники, учётные данные и состояние инфраструктуры. Это ошибка проверки владельца облачного ресурса и предсказуемого имени, а не prompt injection модели ИИ. Уязвимы версии 0.1.0–0.1.5; версия 0.2.0 добавляет ExpectedBucketOwner для S3 и останавливается при несовпадении. Обновление не освобождает уже зарегистрированное имя: проверьте владельца и не возобновляйте сканирование, если bucket чужой.
Имя бакета не подтверждает его владельца
| Граница | Документированное условие | Действие оператора |
|---|---|---|
| Уязвимые версии | Затронуты awslabs.security-agent-mcp-server 0.1.0–0.1.5; в 0.2.0 добавлена проверка владельца. | Обновитесь до 0.2.0 или новее и проверьте фактически запущенную версию пакета. |
| Предсказуемое имя бакета | Имя бакета для сканирования строится из ID аккаунта и региона; его может зарегистрировать другой аккаунт AWS. | Считайте совпавшее имя адресом, а не подтверждением владения. |
| Межаккаунтная загрузка | Уязвимый сервер мог принять бакет по имени без проверки владельца, а затем загрузить туда приватный архив сканирования. | Перед сканированием или загрузкой проверьте, что бакет принадлежит ожидаемому аккаунту. |
| Исправленная проверка владения | ExpectedBucketOwner заставляет S3 сверять владельца и при проверке, и при загрузке. | Обновитесь, проверьте фактического владельца и остановите сканирование, если имя принадлежит третьей стороне; обновление не передаёт бакет. |
Пошаговый сценарий атаки
Исходный код: Уязвимый vs Защищённый вариант
Это схема, а не дословная копия. Одного существования недостаточно: S3 должен сравнивать ожидаемый аккаунт владельца при проверке и записи. Берите его из аутентифицированной идентичности AWS и прекращайте операцию при несовпадении. После обновления отдельно проверьте владельца: оно не передаёт и не освобождает уже зарегистрированное имя. AWS указывает ExpectedBucketOwner для HeadBucket и PutObject: при несовпадении запрос завершается ошибкой 403. Используйте это как fail-closed-проверку, но прежде чем считать bucket чужим, разберите ошибки доступа через авторизованный способ проверки владельца.[2], [8], [9]
Фрагмент исходного кода: Пример AWS SDK по мотивам advisory; это не дословный diff исходного кода.
# Упрощенная уязвимая схема: имя проверяется, но владелец — нет.
s3.head_bucket(Bucket=bucket_name)
s3.put_object(
Bucket=bucket_name,
Key=object_key,
Body=archive_bytes,
)
# Привяжите каждую операцию к ожидаемой учетной записи владельца bucket.
expected_owner = sts.get_caller_identity()["Account"]
s3.head_bucket(
Bucket=bucket_name,
ExpectedBucketOwner=expected_owner,
)
s3.put_object(
Bucket=bucket_name,
Key=object_key,
Body=archive_bytes,
ExpectedBucketOwner=expected_owner,
)
Чек-лист по защите системы для инженеров
- ✓Обновите сервер до 0.2.0 или новее и проверьте активную версию, включая плагины, образы CI и форки.[2], [4]
- ✓До сканирования подтвердите, что bucket принадлежит нужному аккаунту; найденное имя не доказывает владение.[1], [2]
- ✓Передавайте ожидаемый аккаунт через
ExpectedBucketOwnerво все операции S3, включая загрузку.[8], [9] - ✓При несовпадении остановитесь. Если имя чужое, прекратите сканирование и обратитесь в AWS.[1]
- ✓По возможности создайте bucket в аккаунте клиента до первого запуска; применяйте минимальные права и шифрование.[3], [1]
- ✓Проверьте сканирования на уязвимых версиях и смените учётные данные, если архивы могли содержать секреты.[2], [1]
Источники
- AWS Security Bulletin 2026-105-AWS — CVE-2026-87913
- Maintainer GHSA-3jxw-vj8m-8x77
- AWS Security Agent IDE integration and scan bucket workflow
- awslabs.security-agent-mcp-server 0.2.0 release
- NVD — CVE-2026-87913
- MITRE CWE-283 — Unverified Ownership
- MITRE CWE-341 — Predictable from Observable State
- Boto3 HeadBucket — ExpectedBucketOwner
- Boto3 PutObject — ExpectedBucketOwner
- Связанная уязвимость в том же пакете (отдельный CVE): внедрение аргументов Git в AWS MCP, CVE-2026-97662