Почему MCP — это не просто «ещё один протокол»
Model Context Protocol (MCP) позиционируется как стандарт для безопасного взаимодействия ИИ-моделей с внешними ресурсами и инструментами. Документация говорит о контроле доступа, изоляции и аудите. Но когда вы переносите MCP из песочницы в продакшн, особенно в enterprise-среде, открывается совершенно другая картина.
Реальность: Большинство MCP-серверов в открытом доступе написаны разработчиками, а не security-инженерами. Они решают функциональные задачи, но часто игнорируют классические уязвимости, которые в контексте ИИ становятся в разы опаснее.
Скрытая угроза №1: Инъекции через контекст
Самая опасная и недооценённая проблема. MCP позволяет моделям запрашивать контекст из внешних источников (базы данных, API, файловые системы). Но что, если злоумышленник может контролировать что именно модель запросит?
Пример атаки: SQL-инъекция через «естественный язык»
# Типичный MCP-сервер для работы с БД
@mcp.tool()
def query_database(user_query: str) -> str:
"""Выполняет SQL-запрос на основе естественного языка"""
# Преобразуем запрос пользователя в SQL
sql = llm.transform_to_sql(user_query) # ОПАСНОСТЬ!
# Выполняем запрос
result = db.execute(sql) # SQL-инъекция возможна здесь
return resultКазалось бы, LLM должен генерировать безопасный SQL. Но в моей практике DevOps для ИИ я видел случаи, когда специально сформированный промпт заставлял модель генерировать опасные конструкции:
LLM может сгенерировать: "SELECT * FROM orders WHERE id >= 100; DROP TABLE users; --"
Особенно если модель недостаточно обучена на безопасных паттернах или имеет слабые guardrails.
Скрытая угроза №2: Утечка данных через цепочки вызовов
MCP создаёт сложные цепочки вызовов: модель → MCP-сервер → внешний ресурс → ответ → модель. Каждое звено — потенциальная точка утечки.
| Точка утечки | Сценарий | Последствия |
|---|---|---|
| Кэширование промптов | MCP-сервер кэширует запросы для производительности | Конфиденциальные данные в промптах попадают в кэш |
| Логирование отладки | Включены подробные логи для отладки | API-ключи, токены, PII в логах приложений |
| Межсервисное взаимодействие | MCP-сервер вызывает другие внутренние сервисы | Эскалация привилегий через цепочку доверия |
Реальный кейс из практики
В одном из проектов интеграции Multi-modal RAG MCP-сервер для работы с документами:
- Принимал промпт с конфиденциальным вопросом
- Запрашивал векторную БД для поиска релевантных документов
- Логировал весь контекст для отладки производительности
- Логи попадали в централизованную систему, доступную всей команде DevOps
Результат: утечка коммерческой тайны через «безобидные» логи отладки.
Скрытая угроза №3: Атаки на ресурсы через бесконечные циклы
MCP даёт моделям возможность выполнять действия. Что если модель попросит саму себя что-то сделать, создав рекурсивный вызов?
// Упрощённый пример уязвимого MCP-сервера
mcp_server.expose_tool({
name: "analyze_data",
handler: async (params) => {
// Модель может запросить analyze_data внутри analyze_data
const result = await call_llm({
prompt: `Проанализируй: ${params.data}`,
tools: ["analyze_data", "query_db", "call_api"] // Рекурсия возможна!
});
return result;
}
});Эксплойт: Злонамеренный промпт: "Проанализируй этот текст, затем проанализируй результат анализа, затем проанализируй результат анализа результата..." Модель с слабыми guardrails может войти в бесконечную рекурсию, исчерпав квоты API, вычислительные ресурсы или создав огромные счета за использование LLM.
Пошаговый план защиты MCP в продакшене
1Аудит и картографирование
Прежде чем что-то защищать — нужно знать что защищать.
- Инвентаризация всех MCP-серверов: Какие инструменты экспортируются, какие разрешения требуют
- Карта данных: Какие данные проходят через MCP (PII, коммерческая тайна, API-ключи)
- Цепочки вызовов: MCP-сервер → какие внешние сервисы → с какими привилегиями
2Изоляция и минимальные привилегии
Ни один MCP-сервер не должен работать с правами root или иметь доступ ко всей инфраструктуре.
# Пример Docker-конфигурации с изоляцией
services:
mcp-db-server:
image: custom-mcp-db:latest
user: "1001:1001" # Не root!
read_only: true # Файловая система только для чтения
cap_drop:
- ALL # Убираем все capability
cap_add:
- NET_BIND_SERVICE # Только то, что нужно
networks:
- mcp-internal # Изолированная сеть
volumes:
- ./mcp-db-config:/config:ro # Только чтение3Валидация и санитизация входных данных
Не доверяйте LLM в вопросах безопасности. Все входные данные должны проходить strict validation.
from pydantic import BaseModel, validator
from typing import Literal
class DatabaseQuery(BaseModel):
"""Строгая модель для запросов к БД"""
action: Literal["select", "count", "aggregate"] # Только разрешённые действия
table: str
columns: list[str]
limit: int = Field(le=1000) # Максимум 1000 записей
@validator('table')
def validate_table_name(cls, v):
# Разрешаем только алфавитно-цифровые имена таблиц
if not v.isalnum():
raise ValueError('Invalid table name')
return v
@validator('columns', each_item=True)
def validate_column_name(cls, v):
# Защита от SQL-инъекций через имена колонок
if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', v):
raise ValueError('Invalid column name')
return v
# Использование в MCP-сервере
@mcp.tool()
def query_database(raw_query: str) -> str:
# Сначала валидация через строгую модель
try:
query = parse_natural_language_to_model(raw_query) # Возвращает DatabaseQuery
except ValidationError as e:
return f"Invalid query: {e}"
# Только после валидации выполняем безопасный запрос
sql = f"SELECT {', '.join(query.columns)} FROM {query.table} LIMIT {query.limit}"
return execute_safe_query(sql) # Используем parameterized queries4Рейт-лимитирование и мониторинг
Каждый MCP-сервер должен иметь лимиты на:
- Количество вызовов в секунду/минуту
- Максимальный размер возвращаемых данных
- Максимальное время выполнения
- Глубину рекурсии вызовов (особенно важно!)
Как я описывал в статье про Agent Skills, мониторинг должен включать не только метрики, но и семантику запросов.
5Шифрование и контроль доступа
Все коммуникации между MCP-клиентом и сервером должны быть зашифрованы. Но это не всё:
# Пример настройки mTLS для MCP
# Генерация сертификатов для mutual TLS
openssl req -x509 -newkey rsa:4096 -keyout mcp-server.key -out mcp-server.crt -days 365 -nodes
openssl req -newkey rsa:4096 -keyout mcp-client.key -out mcp-client.csr -nodes
openssl x509 -req -in mcp-client.csr -CA mcp-server.crt -CAkey mcp-server.key -out mcp-client.crt -days 365Частые ошибки и как их избежать
| Ошибка | Последствия | Решение |
|---|---|---|
| Доверие LLM в вопросах безопасности | Инъекции, утечки, несанкционированный доступ | Strict validation на стороне MCP-сервера, принцип zero trust |
| Отсутствие лимитов на ресурсы | DoS-атаки через бесконечные циклы, огромные счета за API | Рейт-лимиты, timeout'ы, лимиты на размер данных |
| Подробное логирование конфиденциальных данных | Утечка PII, API-ключей, коммерческой тайны | Маскирование чувствительных данных в логах, разные уровни логирования для prod/dev |
| Избыточные привилегии MCP-серверов | Эскалация привилегий при компрометации одного сервера | Принцип минимальных привилегий, изоляция через containers/namespaces |
FAQ: Ответы на частые вопросы
Q: MCP — это же протокол от Anthropic, разве он не безопасен по умолчанию?
A: Протокол предоставляет возможности для безопасности (аутентификация, транспортное шифрование), но реализация безопасности лежит на разработчиках MCP-серверов. Как и с HTTP: протокол поддерживает HTTPS, но если вы не настроите сертификаты и не будете валидировать входные данные — безопасность будет иллюзией.
Q: Достаточно ли стандартных брандмауэров и WAF для защиты MCP?
A: Недостаточно. Традиционные WAF плохо понимают семантику MCP-запросов. Атака может быть скрыта в «естественном языке» промпта, который WAF пропустит как легитимный текст. Нужны специализированные решения или кастомные правила, понимающие структуру MCP.
Q: Как часто нужно проводить аудит безопасности MCP-инфраструктуры?
A: При каждом изменении:
- Добавлении нового MCP-сервера
- Изменении существующих инструментов (новые параметры, новые возможности)
- Обновлении LLM-модели (могут измениться шаблоны генерации промптов)
- Изменении инфраструктуры (новые сети, новые сервисы)
Плюс регулярные pentest'ы (хотя бы раз в квартал).
Q: Можно ли использовать MCP с чувствительными данными (медицина, финансы)?
A: Можно, но с дополнительными мерами:
- Полная изоляция (air-gapped среда при необходимости)
- Дополнительное шифрование данных в rest (не только в transit)
- Детальный аудит всех операций (кто, что, когда, с какими данными)
- Регулярные проверки compliance (GDPR, HIPAA, PCI DSS в зависимости от отрасли)
Заключение: Безопасность MCP — это процесс, а не состояние
MCP открывает incredible возможности для интеграции ИИ в бизнес-процессы. Но как и с любой мощной технологией, сила становится уязвимостью при неправильном использовании.
Ключевые takeaways:
- Не доверяйте LLM в вопросах безопасности — всегда валидируйте и санитизируйте на стороне MCP-сервера
- Принцип минимальных привилегий — каждый MCP-сервер должен иметь доступ только к тому, что ему абсолютно необходимо
- Глубокий мониторинг — отслеживайте не только метрики, но и семантику запросов
- Регулярный аудит — безопасность устаревает быстрее, чем вы думаете
Как я показывал в статье про обучение нейросети физике дефектов, глубина понимания проблемы определяет качество решения. Безопасность MCP требует именно такого глубинного подхода — понимания не только как работает протокол, но и как его могут сломать.
Начинайте с безопасности с первого дня внедрения MCP. Потому что добавлять security постфактум — в разы дороже и сложнее, чем строить её с самого начала.