Mika Ayenson, PhD

Incorporación de seguridad en flujos de trabajo de LLM: el enfoque proactivo de Elastic

Explorando el enfoque innovador de Elastic para integrar la seguridad en el ciclo de vida de los LLM a fin de proteger contra vulnerabilidades con el AI Assistant de Elastic.

Incorporación de la seguridad en flujos de trabajo de LLM: el enfoque proactivo de Elastic

Recientemente concluimos uno de nuestros eventos trimestrales de Elastic OnWeek, que brinda una semana única para explorar oportunidades fuera de nuestro día a día habitual. De acuerdo con las publicaciones recientes de OWASP y el AISC de la NSA, decidimos dedicar un tiempo a las diez principales vulnerabilidades de OWASP para LLM de forma nativa en Elastic. En este artículo, abordamos algunas oportunidades para detectar actividad maliciosa de LLM con ES|QL, a saber:

  • LLM01: Inyección inmediata
  • LLM02: Manejo de salida inseguro
  • LLM04: Modelo de Denegación de Servicio
  • LLM06: Divulgación de Información Sensible

Elastic proporciona la capacidad de auditar las aplicaciones de LLM en busca de comportamientos maliciosos; Le mostraremos un enfoque con solo cuatro pasos:

  1. Interceptar y analizar las solicitudes y respuestas de LLM
  2. Enriquecimiento de los datos con resultados de análisis específicos de LLM
  3. Envío de datos a Elastic Security
  4. Escribir ES|Reglas de detección de QL que se pueden usar posteriormente para responder

Este enfoque refleja nuestros esfuerzos continuos para explorar e implementar estrategias de detección avanzadas, incluido el desarrollo de reglas de detección diseñadas específicamente para LLM, mientras nos mantenemos al día con las tecnologías emergentes de IA generativa y los desafíos de seguridad. Sobre esta base, el año pasado marcó una mejora significativa en nuestro conjunto de herramientas y en nuestra capacidad general para continuar este camino proactivo hacia adelante.

Elastic lanzó AI Assistant for Security, en el que presenta cómo la plataforma de IA generativa abierta cuenta con la tecnología de Search AI Platform , una colección de herramientas relevantes para desarrollar aplicaciones de búsqueda avanzadas. Respaldado por el aprendizaje automático (ML) y la inteligencia artificial (IA), este asistente de IA proporciona poderosos flujos de trabajo prediseñados, como resúmenes de alertas, sugerencias de flujos de trabajo, conversiones de consultas y consejos de integración de agentes. Te recomiendo encarecidamente que leas más sobre el Asistente de IA de Elastic sobre cómo las capacidades se extienden sin problemas a través de la observabilidad y la seguridad.

Podemos emplear las capacidades del Asistente de IA como una aplicación LLM de terceros para capturar, auditar y analizar solicitudes y respuestas por conveniencia y para ejecutar experimentos. Una vez que los datos están en un índice, escribir detecciones de comportamiento en él se convierte en algo habitual: también podemos aprovechar todo el motor de detección de seguridad. A pesar de que estamos representando la actividad de LLM de Elastic AI Assistant en este experimento, simplemente se usa como un vehículo para demostrar la auditoría de aplicaciones basadas en LLM. Además, este enfoque de proxy está pensado para que las aplicaciones de terceros envíen datos a Elastic Security.

Podemos introducir mecanismos de seguridad en el ciclo de vida de la aplicación interceptando la actividad de LLM o aprovechando las métricas de LLM observables. Es una práctica común abordar las amenazas basadas en avisos mediante la implementación de varias tácticas de seguridad:

  1. Limpiar entradas: desinfecte y valide las entradas del usuario antes de introducirlas en el modelo
  2. Moderación de contenido: Emplee las herramientas de OpenAI para filtrar avisos y salidas perjudiciales
  3. Límites de velocidad y monitoreo: rastree los patrones de uso para detectar actividades sospechosas
  4. Listas permitidas/bloqueadas: Defina entradas aceptables o prohibidas para aplicaciones específicas
  5. Safe Prompt Engineering: Diseñe mensajes prediseñados que guíen el modelo hacia los resultados previstos
  6. Administración de roles de usuario: controle el acceso de los usuarios para evitar acciones no autorizadas
  7. Educar a los usuarios finales: Promover el uso responsable del modelo para mitigar los riesgos
  8. Red Teaming & Monitoring: Pruebe las vulnerabilidades y monitorear continuamente los resultados inesperados
  9. Comentarios de HITL para el entrenamiento de modelos: Aprenda de los problemas marcados por humanos para refinar el modelo con el tiempo
  10. Restrinja el acceso a la API: limite el acceso al modelo en función de las necesidades específicas y la verificación del usuario

Dos poderosas características proporcionadas por OpenAI, y muchos otros implementadores de LLM, es la capacidad de enviar ID de usuario final y verificar el contenido con una API de moderación, características que establecen el estándar para la seguridad de LLM. El envío de identificadores con hash junto con la solicitud original ayuda a la detección de abusos y proporciona comentarios específicos, lo que permite la identificación única del usuario sin enviar información personal. Por otra parte, el punto final de moderación de OpenAI ayuda a los desarrolladores a identificar contenidos potencialmente dañinos, como el discurso de odio, el fomento de las autolesiones o la violencia, lo que les permite filtrar dicho contenido. Incluso va un paso más allá al detectar amenazas e intentos de autolesión.

A pesar de todas las recomendaciones y mejores prácticas para proteger contra avisos maliciosos, reconocemos que no existe una única solución perfecta. Cuando se emplean capacidades como la API de OpenAI, algunas de estas amenazas pueden ser detectadas por el filtro de contenido, que responderá con una notificación de violación de la política de uso:

Este filtrado de contenido es beneficioso para abordar muchos problemas; Sin embargo, no puede identificar más amenazas en el contexto más amplio del entorno, el ecosistema de aplicaciones u otras alertas que puedan aparecer. Cuanto más podamos integrar los casos de uso de la IA generativa en nuestras capacidades de protección existentes, más control y posibilidades tendremos para hacer frente a las posibles amenazas. Además, incluso si se implementan medidas de seguridad de LLM para detener ataques rudimentarios, aún podemos usar el motor de detección para alertar y tomar medidas correctivas futuras en lugar de bloquear o permitir el abuso de manera silenciosa.

Proxy de solicitudes y configuración de LLM

La solución de seguridad óptima integra salvaguardas adicionales directamente dentro del ecosistema de la aplicación LLM. Esto permite enriquecer las alertas con el contexto completo que rodea a las solicitudes y respuestas. A medida que se envían solicitudes al LLM, podemos interceptarlas y analizarlas en busca de posibles actividades maliciosas. Si es necesario, se puede desencadenar una acción de respuesta para aplazar las llamadas HTTP posteriores. Del mismo modo, la inspección de la respuesta del LLM puede descubrir más signos de comportamiento malicioso.

El uso de un proxy para manejar estas interacciones ofrece varios beneficios:

  • Facilidad de integración y administración: Al gestionar el nuevo código de seguridad dentro de una aplicación proxy dedicada, evita incrustar una lógica de seguridad compleja directamente en la aplicación principal. Este enfoque minimiza los cambios necesarios en la estructura de la aplicación existente, lo que permite un mantenimiento más sencillo y una separación más clara de la seguridad de la lógica empresarial. La aplicación principal solo debe reconfigurarse para enrutar sus solicitudes de LLM a través del proxy.
  • Rendimiento y escalabilidad: Colocar el proxy en un servidor separado aísla los mecanismos de seguridad y ayuda a distribuir la carga computacional. Esto puede ser crucial a la hora de escalar las operaciones o gestionar tareas de rendimiento intensivo, lo que garantiza que el rendimiento de la aplicación principal no se vea afectado por el procesamiento de seguridad adicional.

Opción de inicio rápido: Proxy con matraz

Puede proxy de conexiones LLM entrantes y salientes para una configuración inicial más rápida. Este enfoque se puede generalizar para otras aplicaciones de LLM mediante la creación de una aplicación Flask simple basada en Python. Esta aplicación interceptaría la comunicación, la analizaría en busca de riesgos de seguridad y registraría la información relevante antes de reenviar la respuesta.

Existen varios SDK para conectarse a Elasticsearch y manejar las solicitudes de LLM de OpenAI. El repositorio llm-detection-proxy proporcionado muestra los clientes Elastic y OpenAI disponibles. Este fragmento resalta la mayor parte del proxy experimental en una sola ruta de Flask.

@app.route("/proxy/openai", methods=["POST"])
def azure_openai_proxy():
   """Proxy endpoint for Azure OpenAI requests."""
   data = request.get_json()
   messages = data.get("messages", [])
   response_content = ""
   error_response = None

   try:
       # Forward the request to Azure OpenAI
       response = client.chat.completions.create(model=deployment_name, messages=messages)
       response_content = response.choices[0].message.content  # Assuming one choice for simplicity
       choices = response.choices[0].model_dump()
   except openai.BadRequestError as e:
       # If BadRequestError is raised, capture the error details
       error_response = e.response.json().get("error", {}).get("innererror", {})
       response_content = e.response.json().get("error", {}).get("message")

       # Structure the response with the error details
       choices = {**error_response.get("content_filter_result", {}),
                  "error": response_content, "message": {"content": response_content}}

   # Perform additional analysis and create the Elastic document
   additional_analysis = analyze_and_enrich_request(prompt=messages[-1],
                                                    response_text=response_content,
                                                    error_response=error_response)
   log_data = {"request": {"messages": messages[-1]},
               "response": {"choices": response_content},
               **additional_analysis}

   # Log the last message and response
   log_to_elasticsearch(log_data)

   # Calculate token usage
   prompt_tokens = sum(len(message["content"]) for message in messages)
   completion_tokens = len(response_content)
   total_tokens = prompt_tokens + completion_tokens

   # Structure and return the response
   return jsonify({
       "choices": [choices],
       "usage": {
           "prompt_tokens": prompt_tokens,
           "completion_tokens": completion_tokens,
           "total_tokens": total_tokens,
       }
   })

Con el servidor Flask, puede configurar el conector Kibana de OpenAI para usar su proxy.

Dado que este proxy para tu LLM se ejecuta localmente, las credenciales y la información de conexión se gestionan fuera de Elastic, y se puede proporcionar una cadena vacía en la sección de clave de API. Antes de seguir adelante, suele ser una buena idea probar la conexión. Es importante tener en cuenta otras participaciones de seguridad si está considerando implementar una solución de proxy en un entorno real, algo que este prototipo no consideró por brevedad.

Ahora podemos indexar nuestras solicitudes y respuestas de LLM y comenzar a escribir detecciones en los datos disponibles en el índice azure-openai-logs creado en este experimento. Opcionalmente, podríamos preprocesar los datos mediante una canalización de ingesta de Elastic, pero en este ejemplo artificial, podemos escribir detecciones de manera efectiva con el poder de ES|QL.

Ejemplo de datos de solicitud/respuesta de LLM de AzureOpenAI

Apoderado de Langsmith

Nota: El proyecto Langsmith Proxy proporciona un proxy dockerizado para las API de LLM. Si bien ofrece una solución minimizada, al momento de escribir este artículo, carece de capacidades nativas para incorporar herramientas de análisis de seguridad personalizadas o integrar directamente con Elastic Security.

El proxy de LangSmith está diseñado para simplificar la interacción de la API de LLM. Es una aplicación sidecar que requiere una configuración mínima (por ejemplo, LLM API URL). Mejora el rendimiento (almacenamiento en caché, transmisión) para escenarios de alto tráfico. Emplea NGINX para la eficiencia y admite el seguimiento opcional para un seguimiento detallado de la interacción de LLM. Actualmente, trabaja con OpenAI y AzureOpenAI, con soporte futuro planeado para otros LLM.

Posibles ataques de LLM y oportunidades de reglas de detección

Es importante comprender que, aunque las listas documentadas de protecciones no acompañan a algunos LLM, el simple hecho de intentar algunas de estas indicaciones puede ser denegado inmediatamente o resultar en la prohibición en cualquier plataforma empleada para enviar la solicitud. Recomendamos experimentar con precaución y comprender el SLA antes de enviar cualquier mensaje malicioso. Dado que esta exploración aprovecha los recursos de OpenAI, recomendamos seguir la guía de bugcrowd y registrar para obtener una cuenta de prueba adicional empleando su dirección de email @bugcrowdninja.com.

A continuación se muestra una lista de varios ejemplos plausibles para ilustrar las oportunidades de detección. Cada tema de LLM incluye la descripción de OWASP, un mensaje de ejemplo, un documento de muestra, la oportunidad de detección y las posibles acciones que los usuarios podrían realizar si integran mecanismos de seguridad adicionales en su flujo de trabajo.

Si bien esta lista no es extensa actualmente, Elastic Security Labs está llevando a cabo un serial de iniciativas para garantizar el desarrollo futuro, y la formalización de las reglas continuará.

LLM01 - inyección rápida

OWASP Descripción: La manipulación de LLM a través de entradas elaboradas puede provocar accesos no autorizados, violaciones de datos y toma de decisiones comprometida. Referencia aquí.

Ejemplo: Un adversario podría intentar crear avisos que engañen al LLM para que ejecute acciones no deseadas o revele información confidencial. Nota: Herramientas como promptmap están disponibles para generar ideas creativas de inyección de prompts y automatizar el proceso de prueba.

Prompt:

Ejemplo de respuesta:

Oportunidad de regla de detección: en este ejemplo, el LLM respondió negar a manejar cadenas de conexión de base de datos debido a riesgos de seguridad. Hace hincapié en mantener la privacidad de las credenciales y sugiere el uso de métodos seguros como variables de entorno o bóvedas para protegerlas.

Una consulta de coincidencia de indicadores muy frágil pero básica puede tener el siguiente aspecto:

FROM azure-openai-logs |
   WHERE request.messages.content LIKE "*generate*connection*string*"
   OR request.messages.content LIKE "*credentials*password*username*"
   OR response.choices LIKE "*I'm sorry, but I can't assist*"

Una consulta un poco más avanzada detecta más de dos intentos similares en el último día.

FROM azure-openai-logs
| WHERE @timestamp > NOW() -  1 DAY
| WHERE request.messages.content LIKE "*credentials*password*username*"
   OR response.choices LIKE "*I'm*sorry,*but*I*can't*assist*"
   OR response.choices LIKE "*I*can’t*process*actual*sensitive*"
| stats total_attempts = count(*) by connectorId
| WHERE total_attempts >= 2

Tenga en cuenta que hay muchos enfoques para detectar mensajes maliciosos y proteger las respuestas de LLM. Confiar únicamente en estos indicadores no es el mejor enfoque; Sin embargo, podemos mejorar gradualmente la detección con enriquecimiento adicional o numerosos intentos de respuesta. Además, si introducimos un ID en nuestros documentos, podemos mejorar aún más nuestra consulta agregando intentos en función del campo que se correlaciona con un usuario específico.

Ejemplo 2: El efecto Crescendo es un ataque de jailbreak realista en el que un adversario manipula gradualmente un modelo de lenguaje a través de un serial de preguntas aparentemente inocentes que cambian para pedirle al modelo que describa escenarios hipotéticos que involucran el acceso no autorizado y la manipulación de sistemas seguros. Al hacerlo, su objetivo es extraer métodos que podrían eludir las restricciones de seguridad del LLM.

Prompt:

Ejemplo de respuesta:

Con el análisis adicional del filtrado de OpenAI, podemos detectar inmediatamente la primera ocurrencia de abuso.

Oportunidad de regla de detección:

FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
 AND (
     request.messages.content LIKE "*credentials*password*username*"
     OR response.choices LIKE "*I'm sorry, but I can't assist*"
     OR analysis.openai.code == "ResponsibleAIPolicyViolation"
     OR malicious
 )
| STATS total_attempts = COUNT(*) BY connectorId
| WHERE total_attempts > 1
| SORT total_attempts DESC

Sin embargo, a medida que continúa usando el efecto Crescendo, notamos que el pivote de conversación se desbloquea luego del filtro de contenido inicial de OpenAI. Es importante entender que, incluso si tácticas como esta son difíciles de prevenir, todavía tenemos oportunidades para detectarlas.

Las herramientas de análisis adicionales, como LLM-Guard, detectan si la conversación es confidencial, lo que, en este caso, es inexacto. Sin embargo, insinúa oportunidades potenciales para rastrear el comportamiento malicioso a través de múltiples indicaciones. Nota: También podríamos aprovechar las secuencias EQL como alternativa a este ES|Consulta de QL para ayudar a realizar un seguimiento de los comportamientos en varios eventos.

FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
 AND (
     request.messages.content LIKE "*Molotov*"
     OR analysis.openai.code == "ResponsibleAIPolicyViolation"
     OR malicious
 )
| STATS attempts = count(*), max_sensitivity = max(analysis.llm_guard_response_scores.Sensitive) BY connectorId
| WHERE attempts >= 1 AND max_sensitivity > 0.5
| SORT attempts DESC

Esta consulta detecta comportamientos sospechosos relacionados con cócteles molotov en varios eventos mediante el análisis de secuencias de entradas de registro asociadas con un solo usuario/sesión (identificadas por connectorId). El núcleo de consultas filtra los eventos en función de:

  • Content Matching: Busca menciones de "Molotov" en el contenido de la conversación (request.messages.content LIKE "*Molotov*")
  • **Violaciones de la política: Identifica los intentos bloqueados por los filtros de seguridad de OpenAI (analysis.openai.code == "ResponsibleAIPolicyViolation"), lo que indica el inicio de comportamientos potencialmente sospechosos
  • Consideración de marcas maliciosas: incluye registros en los que el sistema marcó el contenido como malicioso (malicious == true), capturando menciones potencialmente sutiles o variadas
  • Análisis a nivel de sesión: Al agrupar eventos por connectorId, analiza la secuencia completa de intentos dentro de una sesión. A continuación, calcula el número total de intentos (attempts = count(*)) y el puntaje de sensibilidad más alta (max_sensitivity = max(analysis.llm_guard_response_scores.Sensitive)) en todos los intentos de esa sesión
  • Marcar sesiones de alto riesgo: Filtra las sesiones con al menos un intento (attempts >= 1) y un puntaje de sensibilidad máxima superior a 0,5 (max_sensitivity > 0.5). Este umbral ayuda a centrar en las sesiones en las que los usuarios discutieron o revelaron contenido potencialmente riesgoso de forma persistente.

Al analizar estos factores en varios eventos dentro de una sesión, podemos comenzar a crear un enfoque para detectar un patrón de discusiones crecientes, incluso si los eventos individuales no se marcan solos.

LLM02 - manejo de salida inseguro

Descripción de OWASP: Si no se validan las salidas de LLM, se pueden producir vulnerabilidades de seguridad posteriores, incluida la ejecución de código que compromete los sistemas y expone los datos. Referencia aquí.

Ejemplo: Un adversario puede intentar explotar el LLM para generar salidas que se pueden emplear para secuencias de comandos entre sitios (XSS) u otros ataques de inyección.

Prompt:

Ejemplo de respuesta:

Oportunidad de regla de detección:

FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
| WHERE (
   response.choices LIKE "*<script>*"
   OR response.choices LIKE "*document.cookie*"
   OR response.choices LIKE "*<img src=x onerror=*"
   OR response.choices LIKE "*<svg/onload=*"
   OR response.choices LIKE "*javascript:alert*"
   OR response.choices LIKE "*<iframe src=# onmouseover=*"
   OR response.choices LIKE "*<img ''><script>*"
   OR response.choices LIKE "*<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>*"
   OR response.choices LIKE "*<IMG SRC=# onmouseover=alert('xxs')>*"
   OR response.choices LIKE "*<IMG onmouseover=alert('xxs')>*"
   OR response.choices LIKE "*<IMG SRC=/ onerror=alert(String.fromCharCode(88,83,83))>*"
   OR response.choices LIKE "*&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>*"
   OR response.choices LIKE "*<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>*"
   OR response.choices LIKE "*<IMG SRC=\"jav&#x0A;ascript:alert('XSS');\">*"
)
| stats total_attempts = COUNT(*), users = COUNT_DISTINCT(connectorId)
| WHERE total_attempts >= 2

Esta pseudoconsulta detecta un posible manejo de salida inseguro mediante la identificación de respuestas LLM que contienen elementos de scripting o intentos de acceso a cookies, que son comunes en los ataques de Cross-Site Scripting (XSS). Es un shell que podría ampliar mediante listas de permitidos o bloqueados para palabras clave conocidas.

LLM04 - modelo DoS

Descripción de OWASP: La sobrecarga de los LLM con operaciones que consumen muchos recursos puede causar interrupciones en el servicio y mayores costos. Referencia aquí.

Ejemplo: Un adversario puede enviar mensajes complejos que consumen demasiados recursos computacionales.

Prompt:

Ejemplo de respuesta:

Oportunidad de regla de detección:

FROM azure-openai-logs
| WHERE @timestamp > NOW() -  1 DAY
| WHERE response.choices LIKE "*requires*significant*computational*resources*"
| stats total_attempts = COUNT(*), users = COUNT_DISTINCT(connectorId)
| WHERE total_attempts >= 2

Esta detección ilustra otro ejemplo simple de cómo se emplea la respuesta de LLM para identificar comportamientos potencialmente abusivos. Aunque este ejemplo puede no representar una amenaza de seguridad tradicional, podría emular cómo los adversarios pueden imponer costos a las víctimas, ya sea consumiendo recursos o tokens.

Ejemplo 2: Un adversario puede enviar mensajes complejos que consumen demasiados recursos computacionales.

Prompt:

Ejemplo de respuesta:

A simple vista, este mensaje parece ser benigno. Sin embargo, el exceso de solicitudes y respuestas detalladas en poco tiempo pueden aumentar significativamente los costos.

Oportunidad de regla de detección:

FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 HOUR
| STATS request_count = COUNT(*), distinct_prompts = COUNT_DISTINCT(request.messages.content) BY connectorId
| WHERE request_count > 50 AND distinct_prompts > 10
| SORT request_count DESC

En el contexto del ejemplo 2, esta consulta de trabajo realiza un seguimiento y analiza de forma eficaz los patrones de uso contando todas las solicitudes y los distintos contenidos de las solicitudes para cada connectorId del azure-openai-logs durante la última hora. Si alguna connectorId envía más de 50 solicitudes con más de diez solicitudes únicas dentro de este periodo de tiempo, indica un posible patrón de uso indebido como el descrito, donde un adversario podría estar modificando las consultas para sondear los detalles del algoritmo de cifrado, lo que podría causar una carga indebida o evadir los sistemas de detección. A continuación, los resultados se ordenan para dar prioridad a las connectorIds con el mayor número de solicitudes, lo que ayuda a identificar rápidamente las fuentes más activas o sospechosas.

LLM06 - divulgación de información sensible

Descripción de OWASP: La falta de protección contra la divulgación de información confidencial en las salidas de LLM puede resultar en consecuencias legales o una pérdida de beneficio competitivo. Referencia aquí.

Ejemplo: Un adversario puede crear indicaciones para extraer información confidencial incrustada en los datos de entrenamiento.

Prompt:

Ejemplo de respuesta:

Oportunidad de regla de detección:

FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
| WHERE request.messages.content LIKE "*common*passwords*used*in*the*dataset*" AND malicious
| stats total_attempts = COUNT(*), users = COUNT_DISTINCT(connectorId)
 BY identified_threats.keyword, analysis.langkit_score
| WHERE total_attempts >= 2

Esta consulta busca registros del último día que contengan solicitudes que pregunten específicamente sobre "contraseñas comunes usadas en el conjunto de datos" para capacitar el modelo y dónde se marcan dichas solicitudes como maliciosas. Agrega estos registros para contar el número de intentos de este tipo e identifica a los distintos usuarios implicados, agrupados por las amenazas identificadas y el puntaje del kit de idiomas. Con cierto enriquecimiento, la inclusión de AND malicious = true garantiza el enfoque en las solicitudes ya marcadas como potencialmente dañinas, lo que ayuda a priorizar las acciones de investigación y respuesta.

Enriquecimiento de las reglas de detección con información de seguridad

Al enrutar las solicitudes de LLM a través de un proxy, podemos aprovechar las herramientas de seguridad especializadas para analizar cada solicitud en busca de signos de intenciones maliciosas. Tras la detección, la solicitud original se puede enriquecer con metadatos adicionales que indiquen la probabilidad de contenido malicioso y el tipo específico de amenaza que representa. Luego, estos datos enriquecidos se indexan en Elasticsearch, lo que crea un estable conjunto de datos de monitoreo, alertas y análisis retrospectivo. Con este enriquecimiento, las oportunidades de detección de LLM de la última sección son posibles.

No profundizamos en todas las herramientas disponibles, pero surgieron varias herramientas de código abierto que ofrecen diferentes enfoques para analizar y cerciorar las interacciones de LLM. Algunas de estas herramientas están respaldadas por modelos de aprendizaje automático capacitados para detectar avisos maliciosos:

  • Rebuff (GitHub): emplea el aprendizaje automático para identificar y mitigar los intentos de ingeniería social, phishing y otras actividades maliciosas a través de interacciones de LLM. Un ejemplo de uso consiste en pasar el contenido de la solicitud a través del motor de análisis de Rebuff y etiquetar las solicitudes con un campo booleano "malicioso" en función de los hallazgos.
  • LLM-Guard (GitHub): Proporciona un motor basado en reglas para detectar patrones dañinos en las solicitudes de LLM. LLM-Guard puede categorizar las amenazas detectadas en función de categorías predefinidas, enriqueciendo las solicitudes con clasificaciones detalladas de amenazas.
  • LangKit (GitHub): Un kit de herramientas diseñado para monitorear y proteger LLM, LangKit puede analizar el contenido de las solicitudes en busca de signos de entradas adversarias o comportamientos de modelos no deseados. Ofrece ganchos para integrar funciones de análisis personalizadas.
  • Vigil-LLM (GitHub): Se centra en el monitoreo y alerta en tiempo real para solicitudes sospechosas de LLM. La integración en la capa de proxy permite la detección inmediata de posibles problemas de seguridad, enriqueciendo los datos de la solicitud con puntajes de vigilancia.
  • Open-Prompt Injection (GitHub): Ofrece metodologías y herramientas para detectar ataques de inyección prompt, lo que permite el enriquecimiento de los datos de las solicitudes con indicadores específicos de compromiso relacionados con las técnicas de inyección prompt.

Nota: La mayoría de estas herramientas requieren llamadas/costos adicionales a un LLM externo, y requerirían más infraestructura para la búsqueda de amenazas de manera efectiva.

Un ejemplo sencillo de implementación que usa LLM-guard y LangKit podría tener el siguiente aspecto:

def analyze_and_enrich_request(
   prompt: str, response_text: str, error_response: Optional[dict] = None
) -> dict:
   """Analyze the prompt and response text for malicious content and enrich the document."""

   # LLM Guard analysis
   sanitized_prompt, results_valid_prompt, results_score_prompt = scan_prompt(
       input_scanners, prompt["content"]
   )
   (
       sanitized_response_text,
       results_valid_response,
       results_score_response,
   ) = scan_output(output_scanners, sanitized_prompt, response_text)

   # LangKit for additional analysis
   schema = injections.init()
   langkit_result = extract({"prompt": prompt["content"]}, schema=schema)

   # Initialize identified threats and malicious flag
   identified_threats = []

   # Check LLM Guard results for prompt
   if not any(results_valid_prompt.values()):
       identified_threats.append("LLM Guard Prompt Invalid")

   # Check LLM Guard results for response
   if not any(results_valid_response.values()):
       identified_threats.append("LLM Guard Response Invalid")

   # Check LangKit result for prompt injection
   prompt_injection_score = langkit_result.get("prompt.injection", 0)
   if prompt_injection_score > 0.4:  # Adjust threshold as needed
       identified_threats.append("LangKit Injection")

   # Identify threats based on LLM Guard scores
   for category, score in results_score_response.items():
       if score > 0.5:
           identified_threats.append(category)

   # Combine results and enrich document
   # llm_guard scores map scanner names to float values of risk scores,
   # where 0 is no risk, and 1 is high risk.
   # langkit_score is a float value of the risk score for prompt injection
   # based on known threats.
   enriched_document = {
       "analysis": {
           "llm_guard_prompt_scores": results_score_prompt,
           "llm_guard_response_scores": results_score_response,
           "langkit_score": prompt_injection_score,
       },
       "malicious": any(identified_threats),
       "identified_threats": identified_threats,
   }

   # Check if there was an error from OpenAI and enrich the analysis
   if error_response:
       code = error_response.get("code")
       filtered_categories = {
           category: info["filtered"]
           for category, info in error_response.get(
               "content_filter_result", {}
           ).items()
       }

       enriched_document["analysis"]["openai"] = {
           "code": code,
           "filtered_categories": filtered_categories,
       }
       if code == "ResponsibleAIPolicyViolation":
           enriched_document["malicious"] = True

   return enriched_document

Esta función podría llamar para cada solicitud que pase por el proxy, y los datos devueltos se anexarán al documento de solicitud antes de enviarlo a Elasticsearch. El resultado es un conjunto de datos detallado y procesable que captura las interacciones sin procesar con el LLM y proporciona información de seguridad inmediata para integrar en nuestras reglas de detección en función de la solicitud y la respuesta. Cerrando el círculo con el ejemplo de LLM01 de inyección de solicitudes, la consulta podría actualizar a algo como esto:

FROM azure-openai-logs
| WHERE @timestamp > NOW() - 1 DAY
| WHERE identified_threats.keyword == "LangKit Injection" OR analysis.langkit_score > 0.4
| stats total_attempts = count(*), users = count_distinct(connectorId) by identified_threats.keyword, analysis.langkit_score
| WHERE users == 1 and total_attempts >= 2

Como puede ver, ambos mecanismos de puntaje son subjetivos y se basan en los resultados devueltos por las herramientas de análisis de solicitudes de código abierto. Esta consulta filtra los registros del día anterior en los que la amenaza identificada es "LangKit Injection" o el puntaje de LangKit es superior a 0.4. A continuación, calcula el total de intentos y cuenta el número de usuarios únicos (agentes) asociados a cada categoría de amenaza identificada y el puntaje de LangKit, filtrando para incluir sólo los casos en los que hay un único usuario implicado (users == 1) y el total de intentos es de dos o más (total_attempts >= 2).

Con estas herramientas adicionales, tenemos una variedad de campos de resultados de análisis disponibles para mejorar nuestras reglas de detección. En estos ejemplos, enviamos la mayoría de los datos tal cual para simplificar. Sin embargo, en un entorno de producción, es crucial normalizar estos campos en todas las herramientas y respuestas de LLM a un esquema como Elastic Common Schema (ECS). La normalización de datos a ECS mejora la interoperabilidad entre diferentes fuentes de datos, simplifica el análisis y agiliza la creación de reglas de seguridad más eficaces y cohesivas.

En la segunda parte de este serial, discutiremos cómo adoptamos un enfoque más formal para el mapeo de campo de ECS y las integraciones.

Opciones alternativas para la auditoría de aplicaciones de LLM

Si bien el uso de un proxy puede ser sencillo, otros enfoques pueden adaptar mejor a una configuración de producción; por ejemplo:

Como era de esperar, estos enfoques tienen limitaciones potenciales, como no ingerir de forma nativa todos los datos de la herramienta de análisis de seguridad LLM generados sin desarrollar una lógica personalizada para admitir herramientas de terceros.

Aprovechamiento de Elastic APM para obtener información detallada de las aplicaciones

Elastic APM proporciona una solución alternativa para monitorear aplicaciones en tiempo real, esencial para detectar cuellos de botella en el rendimiento e identificar solicitudes o consultas problemáticas. Al integrar Elastic APM, los usuarios obtienen información detallada sobre los tiempos de transacción, el rendimiento de las consultas a la base de datos, la eficiencia de las llamadas a API externas y más. Esta visibilidad completa hace que sea más fácil abordar y resolver problemas o errores de rendimiento rápidamente. A diferencia del enfoque de proxy, APM ingiere automáticamente logs en Elastic sobre tu aplicación, lo que brinda la oportunidad de crear reglas de detección de seguridad basadas en los comportamientos observados dentro de tus datos.

Uso de OpenTelemetry para mejorar la observabilidad

Para las aplicaciones que ya emplean OpenTelemetry, aprovechar su integración con Elastic APM puede mejorar la observabilidad sin requerir grandes cambios en la instrumentación. Esta integración admite la captura de una amplia gama de datos de telemetría, incluidos rastreos y métricas, que se pueden enviar sin problemas al Elastic Stack. Este enfoque permite a los desarrolladores seguir usando bibliotecas conocidas mientras se benefician de las estables capacidades de monitoreo de Elastic. La compatibilidad de OpenTelemetry con varios lenguajes de programación y su compatibilidad con el protocolo nativo ( OTLP) de Elastic facilitan la transmisión de datos directa, lo que proporciona una base estable para monitorear sistemas distribuidos. En comparación con el ejemplo de proxy, este enfoque ingiere datos de manera más nativa que mantener un índice independiente y un mecanismo de registro en Elastic.

Auditoría de LLM con Kibana

Al igual que escribir lógica personalizada para tu aplicación de LLM para auditar y enviar datos, puedes probar el enfoque con el Asistente de IA de Elastic. Si te sientes cómodo con TypeScript, considera desplegar una instancia local de Elastic mediante la Guía de introducción de Kibana. Una vez configurado, navega hasta el Elastic AI Assistant y configúralo para interceptar las solicitudes y respuestas de LLM para auditoría y análisis. Nota: Este enfoque rastrea principalmente la integración de LLM específica de Elastic en comparación con el uso de APM y otras integraciones o un proxy para rastrear aplicaciones de terceros. Solo debe considerar con fines de experimentación y pruebas exploratorias.

Afortunadamente, Kibana ya está instrumentado con APM, por lo que si configura un servidor APM, comenzará automáticamente a ingerir registros de esta fuente (configurando elastic.apm.active: true). Consulte el archivo LÉAME para obtener más detalles.

Conclusiones

A medida que continuamos con esta exploración sobre la integración de prácticas de seguridad dentro del ciclo de vida de modelos de lenguaje grandes en Elastic, queda claro que la incorporación de seguridad en los flujos de trabajo de LLM puede proporcionar un camino a seguir para crear aplicaciones más seguras y confiables. Estos ejemplos artificiales, extraídos de nuestro trabajo durante OnWeek, ilustran cómo alguien puede detectar, alertar y clasificar de forma proactiva la actividad maliciosa, aprovechando las soluciones de seguridad que los analistas consideran más intuitivas y eficaces.

También vale la pena señalar que con el enfoque de proxy de ejemplo, podemos incorporar un modelo para detectar y prevenir solicitudes de manera activa. Además, podemos clasificar la respuesta de LLM antes de enviarla de vuelta al usuario si identificamos amenazas maliciosas. En este punto, tenemos la flexibilidad de ampliar nuestras protecciones de seguridad para cubrir una variedad de enfoques defensivos. En este caso, hay una delgada línea entre la seguridad y el rendimiento, ya que cada verificación adicional consumirá tiempo e impedirá el flujo natural de la conversación que los usuarios esperarían.

¡No dude en consultar el proxy de prueba de concepto en llm-detection-proxy y adaptarlo a sus necesidades!

Siempre estamos interesados en escuchar casos de uso y flujos de trabajo como estos, así que, como siempre, comunícate con nosotros a través de problemas de GitHub, chatea con nosotros en nuestro Slack de la comunidad y haz preguntas en nuestros foros de discusión.

El lanzamiento y el momento de cualquier característica o funcionalidad descrita en esta publicación quedan a discreción exclusiva de Elastic. Es posible que cualquier característica o funcionalidad que no esté disponible en este momento no se lance a tiempo o no se lance en absoluto.