Notas prácticas: Incidentes reales de seguridad ocurridos en agentes de IA durante la tercera semana
Guía práctica paso a paso: Incidentes reales de seguridad ocurridos en la tercera semana con agentes de IA: contratos, verificaciones y espacios para código adicional para los equipos que implementan este patrón.
Fuentes: The Week Three Real Security Incidents Happened to AI Agents, and What Each One Actually Teaches
Esta guía reconstruye el proceso desde las materias primas hasta un sistema funcional para: “Los incidentes reales de seguridad de la tercera semana que ocurrieron con agentes de IA y qué enseñan realmente cada uno”. El enfoque está en pasos operativos, verificaciones explícitas y código que se puede insertar directamente en un repositorio sin tener que adivinar su propósito. En la fase de descripción general, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de datos confidenciales y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin necesidad de leer todo el sistema.
Incidente uno: el bot que filtró código privado porque dijiste “además”
Al trabajar en el incidente en la etapa del bot, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Documente junto con ello el camino óptimo y el camino de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Haga un punto de control después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador vuelve a intentar un nodo posterior.
# .github/workflows/agentic-issue-bot.yml
# BEFORE: org-wide token, no membership check, posts directly
name: issue-bot-vulnerable
on:
issues:
types: [assigned]
jobs:
respond:
runs-on: ubuntu-latest
steps:
- name: Fetch context and respond
env:
GH_TOKEN: ${{ secrets.ORG_WIDE_PAT }} # scoped to every repo in the org
run: |
# reads issue.body directly, treats it as trusted instruction
gh issue comment "${{ github.event.issue.number }}" \
--body "$(python3 bot_respond.py "${{ github.event.issue.body }}")"
# AFTER: repo-scoped token, membership gate, draft instead of a live post
name: issue-bot-fixed
on:
issues:
types: [assigned]
jobs:
respond:
runs-on: ubuntu-latest
steps:
- name: Check the issue author is an org member or collaborator
id: gate
env:
GH_TOKEN: ${{ secrets.REPO_SCOPED_PAT }} # scoped to this repo only
run: |
ACTOR="${{ github.event.issue.user.login }}"
ROLE=$(gh api "repos/${{ github.repository }}/collaborators/$ACTOR/permission" \
--jq '.permission' 2>/dev/null || echo "none")
if [ "$ROLE" = "none" ]; then
echo "trusted=false" >> "$GITHUB_OUTPUT"
else
echo "trusted=true" >> "$GITHUB_OUTPUT"
fi
- name: Prepare a draft response instead of posting
if: steps.gate.outputs.trusted == 'true'
env:
GH_TOKEN: ${{ secrets.REPO_SCOPED_PAT }}
run: |
python3 bot_respond.py "${{ github.event.issue.body }}" > draft_reply.md
gh issue edit "${{ github.event.issue.number }}" --add-label "needs-human-review"
# a human reads draft_reply.md and posts it manually, or via a
# second, explicitly human-triggered workflow step
Incidente dos: el CVE que asumió que los desarrolladores eran la parte de confianza
Al trabajar en la fase CVE del Incidente dos, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando falla un paso, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado. Haga una verificación después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.
GITLAB CVE-2026-18252, AFFECTED VS PATCHED
----------------------------------------------------------
BRANCH VULNERABLE RANGE PATCHED VERSION
----------------------------------------------------------
18.x 18.9 - latest 18.x 19.1.7 (upgrade path)
19.1 19.1.0 - 19.1.6 19.1.7
19.2 19.2.0 - 19.2.4 19.2.5
19.3 19.3.0 19.3.1
----------------------------------------------------------
CVSS score: 7.3 (High)
Weakness: CWE-829, inclusion of functionality from an
untrusted control sphere
Required access: authenticated Developer role
GitLab.com SaaS / Dedicated: patched by GitLab, no action needed
Self-managed instances: patch required, urged immediately
----------------------------------------------------------
#!/usr/bin/env bash
# check_gitlab_cve.sh
# Self-hosted, no paid vulnerability scanner required.
# Compares your self-managed GitLab version against GitLab's own
# published security release JSON feed and flags known CVEs.
set -euo pipefail
CURRENT_VERSION=$(curl -s "https://your-gitlab-instance/api/v4/version" \
-H "PRIVATE-TOKEN: $GITLAB_API_TOKEN" | jq -r '.version')
echo "Running GitLab version: $CURRENT_VERSION"
# GitLab publishes security release blog posts with a predictable
# structure; for a production setup, mirror the CVE list into a
# small local file you update whenever GitLab ships a security release,
# and diff your running version against it on a cron job.
KNOWN_VULNERABLE=("18.9.0" "19.1.0" "19.1.6" "19.2.0" "19.2.4" "19.3.0")
for v in "${KNOWN_VULNERABLE[@]}"; do
if [ "$CURRENT_VERSION" = "$v" ]; then
echo "WARNING: running $CURRENT_VERSION, matches a version flagged in CVE-2026-18252 range. Patch now."
exit 1
fi
done
echo "No known match in the local CVE list. Still verify against GitLab's security release page directly."
Incidente tres: el deepfake que quería presupuesto de cómputo, no credenciales
Al trabajar en la fase de deepfake del Incidente tres, anote primero el contrato: los datos de entrada requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Trate esta fase como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina comprobaciones de éxito y evite completaciones parciales silenciosas. Haga puntos de control después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intente nuevamente un nodo posterior. Al trabajar en la fase de deepfake del Incidente tres, anote primero el contrato: los datos de entrada requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema.
La lista de verificación: qué puede hacer realmente un equipo pequeño esta semana
La lista de verificación funciona mejor cuando se trata como una superficie medible. Capture una transcripción clave, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente tanto el camino óptimo como el camino de recuperación. Los intentos repetidos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Mantenga el estado de los gráficos simple y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación después de las interrupciones.
# spend_approval_gate.py
# A minimal, self-hosted out-of-band verification gate.
# No paid identity-verification vendor required, just a shared
# secret rotated on your own schedule and a callback number you
# already have on file, never one supplied in the request itself.
import hmac
import time
THRESHOLD_USD = 50_000
# Rotate this weekly; store it somewhere the approval requester
# (or an attacker impersonating them) never has access to, e.g. a
# password manager entry only finance leads can see.
CURRENT_PASSPHRASE = "harbor-quiet-tuesday"
def requires_out_of_band_check(amount_usd: float) -> bool:
return amount_usd >= THRESHOLD_USD
def verify_out_of_band(spoken_phrase: str) -> bool:
# constant-time compare so a partial match can't be timed out
return hmac.compare_digest(spoken_phrase.strip().lower(),
CURRENT_PASSPHRASE.lower())
def approve_spend(amount_usd: float, spoken_phrase: str = "") -> str:
if not requires_out_of_band_check(amount_usd):
return "approved"
if verify_out_of_band(spoken_phrase):
return "approved after out-of-band verification"
return "BLOCKED: verify via a known callback number or the current passphrase before approving"
Qué tienen en común los tres
La etapa de “Qué” funciona mejor cuando se trata como una superficie medible. Consiga un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una sola responsabilidad y no a un proceso complicado. Mantenga el estado del grafo simple y tipado; los bloques anidados ocultan qué nodo escribió qué campo y causan interrupciones en la continuación del proceso.
Lista de verificación operativa
La etapa de la lista de verificación operativa funciona mejor cuando se trata como una superficie medible. Consiga un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance.
Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la fase de demostración a entornos compartidos.
Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación después de las interrupciones.
Añada una prueba de funcionamiento que ejerza la ruta crítica en CI con fixtures, y no con APIs pagadas en tiempo real, siempre que lo permitan los presupuestos.
Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un único lugar que los operadores puedan auditar sin tener que leer todo el grafo.
Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación después de las interrupciones.
Antes de promocionar la pila, congele las versiones, capture una transcripción de referencia para la ruta crítica y confirme los pasos de reversión. Los entornos compartidos necesitan límites de velocidad, verificaciones de tenencia y un propietario claro para la rotación de secretos. Prefiera una fiabilidad sencilla a demostraciones ingeniosas pero puntuales.
Nota por lotes para 9590a2274c4f: mantenga las claves del proveedor fuera del repositorio, establezca un límite para los tokens por sesión y almacene las transcripciones junto a los archivos de evaluación para que los cambios posteriores en el modelo sigan siendo comparables.
Al trabajar en la etapa 0 de las notas de fortalecimiento, anote primero el contrato: entradas requeridas, señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Registre los tiempos y el costo de tokens o consultas junto a los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando se pasa de entornos de demostración a entornos compartidos.
Detalle de fortalecimiento 0/772: mida el tiempo de ejecución, la clase del error y el gasto en tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en observaciones anecdóticas.
La etapa 1 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ejemplar, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente tanto el camino óptimo como el camino de recuperación juntos. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.
Detalle de fortalecimiento 1/772: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de anécdotas.
Para la etapa 2 de las notas de fortalecimiento, defina las entradas, el responsable de la tarea y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la tarea a partir de un punto de control conocido sin tener que adivinar el estado oculto. Trate esta etapa como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace las completaciones parciales silenciosas.
Detalle de refuerzo 2/772: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
Al trabajar en la tercera fase de la nota de refuerzo, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el grafo.
Detalle de refuerzo 3/772: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
La etapa 4 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ejemplar, un caso de fallo y la nota de reversión antes de ampliar el alcance. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado.
Detalle de fortalecimiento 4/772: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
Para la fase 5 de las notas de fortalecimiento, defina los insumos, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Registre los tiempos de ejecución y el costo de tokens o consultas junto con los resultados funcionales. La visibilidad temprana del costo evita facturas inesperadas cuando el proceso pasa de entornos de demostración a entornos compartidos.
Detalle de fortalecimiento 5/772: mida el tiempo de ejecución, la clase del error y el gasto en tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en observaciones anecdóticas.
Al trabajar en la fase 6 de las notas de fortalecimiento, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código.
Documente tanto el camino óptimo como el de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.
El detalle 6/772 de fortalecimiento: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de anécdotas.
La fase 7 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Trate esta fase como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina las verificaciones de éxito y rechace las completaciones parciales silenciosas.
Detalle de fortalecimiento 7/772: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
Para la etapa 8 de la nota de fortalecimiento, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar que los operadores puedan auditar sin tener que leer todo el sistema.
Detalle de fortalecimiento 8/772: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
Al trabajar en la fase 9 de las notas de fortalecimiento, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Prefiera unidades pequeñas y verificables a scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado.
Detalle de fortalecimiento 9/772: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
La fase 10 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Registre los tiempos y el costo en tokens o consultas junto con los resultados funcionales. La visibilidad temprana de los costos evita facturas inesperadas cuando el proceso pasa de la demostración a entornos compartidos.
Detalle de fortalecimiento 10/772: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
Para la etapa 11 de la nota de fortalecimiento, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Documente tanto la ruta óptima como la ruta de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.
Detalle de fortalecimiento 11/772: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
Al trabajar en la fase 12 de las notas de fortalecimiento, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Trate esta fase como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina las comprobaciones de éxito y rechace las completaciones parciales silenciosas.
Detalle de fortalecimiento 12/772: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
La fase 13 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción de referencia, un caso de fallo y la nota de reversión antes de ampliar el alcance. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar que los operadores puedan auditar sin tener que leer todo el sistema.
Detalle de fortalecimiento 13/772: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
Para la fase 14 de la nota de fortalecimiento, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables sobre scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad en lugar de a un proceso complicado.
Detalle de fortalecimiento 14/772: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.
Al trabajar en la fase 15 de las notas de fortalecimiento, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la fase de demostración a entornos compartidos.
Detalle de fortalecimiento 15/772: mida el tiempo empleado, la clase del error y el gasto en tokens para esta nota, y luego decida si mantener la modificación basándose en un conjunto fijo de preguntas en lugar de en observaciones anecdóticas.
Lecturas relacionadas
- Notas prácticas: Inyección de prompt y seguridad de agentes: El problema no resuelto — Guía paso a paso de las Notas prácticas: Inyección de prompt y seguridad de agentes: El problema no resuelto: contratos, verificaciones y espacios para código listo para usar para los equipos que implementan este patrón.
- Notas prácticas: Construyendo agentes de IA, parte 1: Definiendo el propósito, diseñando — Guía paso a paso de las Notas prácticas: Construyendo agentes de IA, parte 1: Definiendo el propósito, diseñando: contratos, verificaciones y espacios para código listo para usar para los equipos que implementan este patrón.