Ir al contenido

Referencia de seguridad del servidor MCP

Qué es esto

Esta página documenta el modelo de seguridad para el servidor MCP de ComStack: las amenazas que está diseñado para mitigar, los controles en capas sobre operaciones destructivas y los ganchos de monitorización operativa disponibles para los administradores del proyecto.

Modelo de amenazas

AmenazaMitigación
Recorrido de ruta o inyección mediante IDs suministrados por el llamadorTodos los identificadores suministrados se validan contra un patrón de lista blanca estricto en cada punto de entrada
Radio de explosión de proyecto incorrecto (publicar en el proyecto equivocado)(a) project_id por herramienta con verificación de rol; (b) eco de project_name requerido en herramientas destructivas; (c) simulacro de publish + token publish-confirm vinculado a un hash de manifiesto
Reutilización de un token de actualización comprometidoRevocación de la familia de tokens de actualización tras uso duplicado: toda la familia se invalida si se reutiliza un token
Reutilización de una confirmación de publicaciónLos tokens de confirmación son de un solo uso, con TTL de 5 minutos, vinculados a (usuario, proyecto, hash_manifiesto). El servidor reconstruye el manifiesto al confirmar y rechaza si los borradores han cambiado
Escalada de privilegios mediante caché de roles obsoletaEl TTL de la caché de roles es de 30s; la caché de lista de herramientas filtradas es de 30s. Las revocaciones de roles surten efecto en un ciclo de caché
Fuga de argumentos sensibles al registro de auditoríaEl registrador de auditoría redacta argumentos que coinciden con patrones de secreto, token, contraseña y clave, incluyendo confirmation_token, de forma recursiva
XSS mediante inyección en metadata.headLista blanca de etiquetas, atributos y protocolos; las entradas no permitidas se rechazan directamente
Exfiltración de CSS mediante custom_css@import, url() fuera de origen, :visited y expression() se bloquean mediante una lista blanca de propiedades y fuentes
DoS por tamaño de cuerpoLímite de 1 MB en todas las rutas API y MCP; límite de 10 MB en carga de imágenes
Fuerza bruta ante fallos de autenticaciónLimitador de fallos por IP (10 por minuto)
Abuso de CORSLista blanca de orígenes explícita; los orígenes no permitidos no reciben cabeceras CORS
Llamadores Cloud-to-server suplantando un Origin de navegadorValidación explícita de Origin en POST /mcp. Las peticiones sin Origin pasan (servidor a servidor). Los orígenes no permitidos devuelven HTTP 403 antes de la autenticación
LLM escribe en la página incorrecta (colisión de slug)create-page rechaza (a) un ID de documento existente y (b) otra página con el mismo (slug, idioma). Ambos errores incluyen la ruta conflictiva y la acción de recuperación
Página publicada con metadatos mal formadosValidador de una sola pasada en cada create-page / update-page. Devuelve TODOS los problemas a la vez con valores permitidos, ejemplos y cadenas de corrección
Publicaciones concurrentes corrompiendo documentosBloqueo de publicación consultivo con TTL de 60s dentro de la transacción de promoción
Borradores traducidos publicados sin validarLa traducción escribe borradores; se ejecuta una validación de segunda pasada antes de la promoción
Claves API personales en servicios de larga duraciónLas claves personales se rechazan en /mcp tras un periodo de gracia de 60 días; las claves de servicio son la ruta correcta a largo plazo para llamadores headless
Necesidad de revertir una mala publicaciónrevert-publish restaura el sitio desde la instantánea de publicación en menos de 1 hora

Defensa en profundidad: la ruta de publicación

Una sola llamada destructiva contra el proyecto equivocado afectaría al sitio en vivo del usuario. Cinco capas independientes deben alinearse antes de que se despliegue cualquier byte:

  1. Token OAuth Bearer debe ser válido y no haber expirado.
  2. Verificación de rol — el llamador debe tener al menos manager en el project_id suministrado. Escalera de roles (de menor a mayor): noneguestmembermanageradmin.
  3. Eco de project_name — el project_name suministrado debe coincidir exactamente con el nombre almacenado del proyecto (sin distinguir mayúsculas, recortado). Llame a get-project-state primero para obtener el nombre exacto.
  4. Simulacro de publishpublish devuelve un manifiesto y un token de confirmación pero no despliega. El agente muestra el manifiesto al humano para su revisión.
  5. publish-confirm con token — el token es de un solo uso, con TTL de 5 minutos, vinculado a usuario + proyecto + hash de manifiesto. En el momento de la confirmación, el servidor reconstruye el manifiesto y rechaza si los borradores o el tema han cambiado desde el simulacro.

Si alguna capa rechaza, la publicación no se ejecuta.

Monitorización operativa

Registro de auditoría: cada llamada mutante exitosa o fallida se escribe en el registro de auditoría con una carga útil de argumentos redactada. Consulte a través del panel de control o la CLI. Los registros de auditoría nunca son legibles por el cliente; el servidor utiliza exclusivamente el SDK de administración.

Cloud Logging: filtre por [mcp] para la identidad por petición, [security] para activaciones del limitador de tasa y [promote] para transiciones de la máquina de estados de publicación.

Bloqueo de publicación: un documento de bloqueo está presente durante una publicación activa, con un campo expires_at. Los bloqueos obsoletos tras su expiración se eliminan automáticamente.

Errores comunes

ErrorCausaSolución
403 project_name mismatchEl project_name suministrado no coincide con el nombre almacenadoLlame a get-project-state y copie project_name exactamente
403 insufficient roleEl rol del llamador es inferior al mínimo de la herramientaConfirme que el llamador tiene al menos el rol manager en el proyecto
409 publish_lockedOtra publicación está en cursoEspere a que la publicación en curso finalice o confirme que el bloqueo ha expirado
410 token expiredEl TTL del token de confirmación (5 min) ha expiradoLlame a publish de nuevo para obtener un token nuevo
409 manifest_changedLos borradores cambiaron entre publish y publish-confirmLlame a publish de nuevo para obtener un manifiesto que refleje el estado actual

Relacionado

Última actualización: