Una función que responde preguntas sobre documentos puede recuperar texto relevante y enviarlo a un modelo de IA. Ese texto, sin embargo, no siempre es inocuo: un documento, una página web o un archivo aportado por un usuario puede contener frases que intenten cambiar la tarea, obtener información ajena o provocar una acción. Este riesgo se conoce como inyección de prompts en documentos, o inyección indirecta, porque las instrucciones llegan dentro del contenido procesado y no necesariamente en la pregunta del usuario.
La mitigación no consiste en encontrar una frase perfecta para el mensaje de sistema. Consiste en diseñar la aplicación para que el contenido recuperado no pueda modificar permisos, políticas ni decisiones de negocio, y para que una respuesta del modelo nunca sea una autorización suficiente para actuar.
Qué riesgo se debe controlar

Un documento puede contener instrucciones explícitas, como “ignora las instrucciones anteriores”, o texto más engañoso, como una petición de revelar datos internos. También puede incluir instrucciones ocultas en contenido extraído de HTML, comentarios, metadatos o texto generado por OCR. Si ese material se mezcla sin distinción con las instrucciones de la aplicación, el modelo podría seguir parte de él, resumirlo de forma sesgada o generar una respuesta fuera de lo previsto.
El riesgo depende de lo que la función pueda hacer. Un asistente que solo redacta una respuesta para revisión tiene un impacto distinto de uno que puede consultar cuentas, emitir reembolsos o enviar mensajes. Antes de exponer la función a usuarios, hay que definir qué información puede recibir, qué respuestas puede producir y qué consecuencias pueden derivarse de ellas.
La inyección no demuestra por sí sola que se hayan vulnerado los controles de acceso de la aplicación. Sí puede exponer información que se incluyó indebidamente en el contexto o inducir al modelo a solicitar una operación. La protección debe abarcar tanto la entrada como los datos disponibles y las acciones posteriores.
Separar datos de políticas y permisos
El contenido recuperado debe aportar evidencia para responder, no convertirse en una fuente de autoridad. Un documento puede describir una política empresarial, pero la aplicación debe determinar por separado si el usuario está autorizado a consultar ese documento o realizar una operación relacionada. No se delega esa decisión al texto ni a la respuesta generada.
- Autorización antes de recuperar: aplica controles de acceso en la búsqueda y filtra los documentos según la identidad y los permisos vigentes del usuario.
- Contexto mínimo: envía solo los fragmentos necesarios para la tarea. No incluyas datos de otras cuentas, secretos, credenciales ni información que el modelo no necesite.
- Políticas fuera del modelo: calcula permisos, límites y condiciones de negocio en código de la aplicación o en servicios autorizados.
- Respuesta como propuesta: trata la salida del modelo como contenido que se debe validar, no como una instrucción ejecutable.
Una instrucción de sistema puede ayudar a expresar el comportamiento esperado, por ejemplo indicando que el texto recuperado es material de referencia. No es una frontera de seguridad: no garantiza que el modelo ignore instrucciones maliciosas ni sustituye los controles de acceso, la validación y las restricciones técnicas.
Diseñar el flujo PHP con límites explícitos
En PHP, conviene separar las etapas de autorización, recuperación, construcción del contexto, llamada al modelo y validación de la salida. Esa separación facilita probar cada límite y evita que un resultado de IA se conecte directamente con una operación sensible.
El siguiente fragmento es pseudocódigo ilustrativo, no una llamada ejecutable a un cliente concreto. La forma de construir la solicitud y los campos aceptados dependen de la API y del SDK utilizados:
$user = $auth->currentUser();
$documents = $repository->searchAuthorized($user, $question);
$snippets = $contextBuilder->selectRelevant($documents, $maxItems);
// Pseudocódigo: adapta la solicitud a la API concreta.
$response = $aiClient->answer([
'task' => 'Responde usando el material de referencia; no autoriza acciones.',
'untrusted_context' => $snippets,
'question' => $question,
]);
$answer = $responseValidator->validate($response);
return $answer;
Los nombres del ejemplo son ilustrativos. Etiquetar el contexto como no confiable ayuda a comunicar su función, pero no lo aísla de forma infalible: ni el formato ni las instrucciones impiden por sí solos que el modelo siga una instrucción incrustada. La separación efectiva depende también de los datos enviados, los permisos aplicados fuera del modelo y las capacidades disponibles.
Normaliza y limita el contenido extraído antes de incorporarlo: fija tamaños máximos, elimina formatos que no necesites y trata con cuidado el texto obtenido por OCR o de páginas externas. Evita concatenar documentos sin límites ni incluir el historial completo de una conversación por defecto. Conserva una referencia al origen de cada fragmento si necesitas explicar o auditar la respuesta, sin incluir su contenido sensible en los registros.
Reducir el impacto de una respuesta manipulada
Limita las herramientas accesibles al modelo a las necesarias para la función concreta. Si la tarea solo requiere responder preguntas, no le concedas herramientas de escritura ni acceso general a servicios internos. Si necesita consultar datos, expón una operación acotada que aplique autorización por solicitud, en lugar de credenciales amplias o acceso arbitrario a una base de datos.
Cuando el modelo proponga una acción, la aplicación debe validarla en un flujo independiente. Comprueba la identidad, los permisos, los parámetros, las reglas de negocio y las condiciones actuales del recurso en el momento de ejecutar. Para acciones de alto impacto, solicita confirmación explícita o revisión humana. Una respuesta textual del modelo, incluso si parece segura o cita un documento, no sustituye esa autorización.
Valida también la salida antes de mostrarla o procesarla: comprueba el formato esperado, limita la longitud y rechaza campos o valores fuera de los permitidos. Si se espera una estructura concreta, analiza y valida sus campos con reglas deterministas. El escape de salida y las defensas contra inyección en HTML, SQL o comandos siguen siendo necesarios; la generación por IA no vuelve confiable el texto producido.
Probar ataques y comportamientos esperados
Las pruebas deben cubrir el flujo completo, no solo si el modelo responde correctamente a una instrucción de sistema. Prepara documentos benignos y documentos adversariales que intenten alterar la tarea, solicitar datos no autorizados o inducir una acción. Incluye variaciones en el formato de origen, como texto extraído de HTML, documentos largos y contenido con instrucciones mezcladas con información legítima.
- Comprueba que la búsqueda nunca devuelva documentos fuera de los permisos del usuario, aunque la pregunta solicite explícitamente esos datos.
- Verifica que los documentos adversariales no habiliten herramientas ni cambien las reglas de negocio.
- Confirma que una respuesta mal formada o inesperada se rechace y que una operación sensible requiera autorización independiente.
- Evalúa respuestas útiles y correctas en documentos benignos para detectar si las restricciones degradan la función de forma inaceptable.
- Repite las pruebas cuando cambien el modelo, la plantilla de instrucciones, el recuperador, las herramientas o el proceso de extracción.
Define criterios de aceptación observables: qué datos nunca deben aparecer, qué acciones deben permanecer bloqueadas y cómo debe responder el sistema cuando no hay evidencia suficiente. Una prueba aislada no garantiza seguridad, pero una batería repetible ayuda a detectar regresiones y a comparar cambios de configuración.
Registrar señales sin acumular datos sensibles
Para investigar fallos, registra identificadores de solicitud, versión de la configuración, identificadores o referencias internas de los documentos consultados, decisiones de autorización, herramientas invocadas y resultado de las validaciones. Registrar una referencia no significa almacenar el documento ni sus fragmentos. Evita guardar fragmentos sensibles salvo que exista una necesidad concreta y controles específicos de acceso, protección y retención.
Añade métricas de rechazos, errores de formato y fallos del proveedor para distinguir problemas de seguridad de problemas operativos. Evita guardar automáticamente prompts completos, documentos y respuestas si contienen datos personales, secretos comerciales o información regulada. Define retención, acceso y redacción de datos sensibles; cuando sea suficiente, registra hashes, identificadores y eventos estructurados. Asegura que los registros no se conviertan en una nueva vía para exponer el contenido que la función debía proteger.
Lista de comprobación antes de habilitar la función

- ¿Se comprueban permisos antes de recuperar cada documento?
- ¿El contexto enviado es mínimo, acotado y tratado como entrada no confiable?
- ¿Las políticas y reglas de negocio se aplican fuera del modelo?
- ¿Las herramientas están limitadas y cada operación vuelve a comprobar autorización?
- ¿Se validan las respuestas antes de mostrarlas o convertirlas en acciones?
- ¿Hay revisión humana o confirmación para decisiones de impacto elevado?
- ¿Existen pruebas adversariales repetibles y registros con retención controlada?
Si alguna respuesta es negativa, limita el alcance de la función o mantén las acciones en modo de propuesta hasta cerrar esa brecha. La defensa frente a la inyección de prompts en documentos no depende de que el modelo interprete siempre bien el contenido: depende de que los límites de acceso y de operación sigan funcionando incluso cuando el modelo se equivoca.



