# Convencieron a un agente para que enviara 150.000 $ en código morse

> Sin exploit y sin clave robada: solo un mensaje que el modelo aceptó obedecer. La inyección de prompts no se parchea, así que ¿qué puede expresar?

- Source: https://defiloops.com/es/blog/talked-into-sending-150000
- Published: 2026-09-01
- Category: Security
- Tags: security, prompt-injection, agents, permissions
- Author: DeFiLoops

---
En mayo de 2026 alguien [sacó 150.000 $ de una cartera integrada con IA](https://www.giskard.ai/knowledge/how-grok-got-prompt-injected-an-x-user-drained-150-000-from-an-ai-wallet) sin encontrar un solo fallo.

Envió un NFT de membresía a la cartera, lo que la movió en silencio a un nivel de permisos superior. Después publicó una
respuesta en X con una instrucción escondida dentro de código morse. El agente —Grok, conectado a un bot de trading—
descodificó el morse, leyó la instrucción, decidió que era una orden legítima y autorizó la transferencia.

Sin exploit. Sin clave robada. Sin servidor comprometido. Al modelo simplemente se lo pidieron con educación, en un formato
que nadie había pensado en desconfiar.

## Dos fallos, y solo uno se discute

Ambos tienen nombre: [OWASP LLM01:2025 y LLM06:2025](https://genai.owasp.org/llm-top-10/) — la primera y la sexta
entradas de la lista estándar de fallos en aplicaciones con modelos de lenguaje.

<Compare left="Inyección de prompt" right="Agencia excesiva" verdict>
  <Fragment slot="left">
    El modelo no distinguió una instrucción *de su principal* de una instrucción *en su entrada*. Todo el mundo trabaja en
    esto. Nadie lo ha resuelto.
  </Fragment>
  <Fragment slot="right">
    Una vez convencido, el modelo pudo expresar «envíalo todo a esta dirección».

    Este no es un problema del modelo en absoluto. Es una pregunta sobre qué permite escribir el sistema que lo rodea.
  </Fragment>
</Compare>

El primer fallo es el que se lleva los titulares. El segundo es el que decidió cuánto costó.

<Callout type="warn" title="Trate la inyección como un hecho dado">
  El contenido codificado lo hace concreto: cualquier texto que pase por una capa de traducción o descodificación debería
  tratarse como potencialmente inyectado. El morse funcionó. También funcionará base64, también una imagen, también un idioma
  en el que no se evaluaron las barreras. No se pueden enumerar las codificaciones.
</Callout>

Si la inyección va a ocurrir, la pregunta de diseño no es *cómo impedimos que engañen al modelo*. Es **qué puede hacer
realmente un modelo engañado**.

## La respuesta del sector, y por qué se queda corta

Lea una docena de páginas de proveedores sobre seguridad de carteras agénticas y obtiene la misma lista: mínimo privilegio,
claves de sesión acotadas, límites por transacción y diarios, una lista blanca de destinatarios, confirmación humana para todo
lo irreversible, claves aisladas del proceso de razonamiento.

Todo es bueno. Parte no está ocurriendo: **[el 45,6 % de los equipos](https://www.gravitee.io/blog/state-of-ai-agent-security-2026-report-when-adoption-outpaces-control) siguen compartiendo una sola clave de API entre sus
agentes**, lo que hace casi imposible rastrear o detener a un agente que se ha torcido. Conviene tratar con cuidado las cifras publicadas sobre brechas de agentes: el dato
destacado del primer trimestre de 2026 está dominado por un único incidente que las
fuentes primarias atribuyen a portátiles de directivos comprometidos, no a nada propio de
los agentes. El modo de fallo bien documentado es más estrecho y más útil: ataques a la
memoria de los agentes y a los protocolos que los conectan a sus herramientas.

Pero el problema de fondo es que toda la lista comparte una suposición:

<Quote>
  Los alcances de permiso deben definirse con precisión, pero definirlos con precisión es difícil, porque los agentes actúan
  sobre intención expresada en lenguaje y el lenguaje es ambiguo.
</Quote>

Esa frase, o una casi idéntica, aparece por todo el sector. Se trata como un problema difícil que hay que gestionar con
alcances cada vez más estrechos.

Es un problema difícil. Solo es inevitable si el modelo compone llamadas.

## Nosotros quitamos el campo en su lugar

El agente aquí no escribe instrucciones. Rellena un formulario fijo de casillas etiquetadas, tomadas de un catálogo cerrado de
operaciones.

<Spec title="Qué puede llevar el formulario" rows={[
  ['importe', 'Una cantidad, en la escala del propio activo'],
  ['activo', 'Un símbolo de la lista de la red, nunca una dirección'],
  ['red', 'Una de las redes admitidas'],
  ['rol', 'Un destino con nombre, como «la cuenta del propietario», nunca una dirección en bruto'],
  ['mercado', 'Un nombre de mercado curado, nunca un identificador'],
  ['puntos básicos, fecha límite, precio, tick', 'Tipos numéricos acotados'],
]} />

<Callout type="danger" title="Deliberadamente no hay tipo «bytes en bruto» ni tipo «cualquier cosa»">
  Cualquiera de los dos permitiría a un llamante colar una instrucción por un campo, y eso desharía toda la propiedad. No hay
  casilla para una dirección de destino ni casilla para un payload.
</Callout>

Así que ejecute el ataque del morse contra esto. El modelo está convencido: asúmalo por completo. Ahora quiere enviar sus fondos
a un atacante.

No puede escribirlo. Los destinos son **roles**, resueltos desde su cuenta en el momento en que el paso se ejecuta. No hay ningún
campo donde pudiera ir la dirección de un atacante, así que nada tiene que detectar el intento.

<Steps>
  <Step title="Una operación que no esté en la lista no puede nombrarse">
    Un plan que nombre algo fuera del catálogo se rechaza al escribirse, no se intenta y falla a medio camino.
  </Step>
  <Step title="Todo lo que se produce va a usted">
    El destino es un rol que se resuelve desde su cuenta, nunca un valor que el plan suministre.
  </Step>
  <Step title="Los límites están fijados en su cuenta">
    Por activo, por periodo. Nada de nuestro lado puede elevarlos.
  </Step>
  <Step title="El agente es un contrato, no una clave">
    Una clave puede robarse y usarla quien la tenga. Un contrato solo puede nombrarse o no, y el nombramiento es de sentido
    único, así que una cuenta no puede reorientarse nunca hacia un agente distinto.
  </Step>
</Steps>

## Donde esto deja de ser cómodo

Todo lo anterior es real y nada de ello nos hace seguros en general. Tres cosas que sopesar en contra:

<Callout type="warn" title="La protección es una lista de prohibiciones">
  Lo que impide que el agente se porte mal prohíbe acciones concretas en lugar de permitir solo las conocidas-buenas. Bloquea por
  completo una toma de control: el agente nunca puede convertirse en propietario ni entregar su cuenta a otro. No bloquea todas las
  formas en que el valor podría moverse mediante una acción que nadie pensó en prohibir.

  **Hemos probado cuatro ataques de ese tipo contra nosotros mismos**, sobre una copia de la red real de Base, con la misma forma que
  producción.
</Callout>

Son alcanzables en dos situaciones: un modo permisivo en el que no operamos por defecto, y allí donde alguien tiene la clave keeper
directamente y por tanto nunca pasa por nuestro servicio de firma. En operación normal, ese servicio no produce la forma de instrucción
que llega hasta ellos. Es una protección real y no es lo mismo que el agujero esté cerrado.

Segundo: **no hay auditoría externa.** Toda garantía que damos es nuestra propia comprobación.

Tercero: el servicio que guarda la clave keeper se niega a arrancar en producción, a propósito, porque actualmente mantiene esa clave en
memoria.

## Qué llevarse realmente de la historia del morse

No que un producto fuera descuidado. El error concreto —una transferencia de NFT que eleva en silencio un nivel de permisos— es
inusual, pero la forma no lo es.

La forma es: **un sistema donde ser convencido y poder actuar son el mismo evento.**

<Quote cite="La única defensa estructural que conocemos">
  La inyección no se puede evitar. La expresividad sí se puede quitar.
</Quote>

Si está evaluando cualquier agente que toque dinero, esa es la pregunta que merece hacerse, y se puede responder sin fiarse de la página
de seguridad de nadie. Pregunte qué puede escribir el agente. Si la respuesta incluye una dirección, todos los demás controles son un
filtro entre un modelo persuadible y sus fondos, y los filtros se evalúan contra los ataques que alguien ya pensó.

El nuestro no incluye una dirección. Aun así preferiríamos que diera por hecho que se nos ha escapado algo, porque en cuatro ocasiones se
nos escapó.