Claude Code habría escondido una señal en sus solicitudes: un apóstrofo puede marcar tu entorno

Una explicación clara de la controversia sobre la marca de agua en solicitudes de Claude Code: cómo podría revisar ANTHROPIC_BASE_URL, zona horaria y listas de dominios, y ocultar el resultado dentro de una frase de fecha.

Claude Code ha estado recientemente en el centro de una controversia: según informes de ingeniería inversa, algunas versiones de Claude Code podrían leer información del entorno local bajo ciertas condiciones y codificar el resultado de la detección dentro del system prompt enviado al servidor. El mecanismo no sería un campo extra de telemetry evidente. En su lugar, modificaría una línea de fecha aparentemente normal, por ejemplo Today's date is 2026-06-30..

Lo más interesante de la discusión pública no es el resultado de una cuenta suspendida, sino el flujo de detección. Muestra cómo una herramienta local de programación con IA puede llevar señales del entorno del cliente dentro de una solicitud normal sin añadir una llamada de red adicional. Para los desarrolladores, eso importa más que el riesgo de cuenta por sí solo.

Este artículo resume detalles técnicos que aparecen repetidamente en publicaciones públicas de ingeniería inversa y discusiones de la comunidad. Como este tipo de análisis depende de versiones concretas y resultados de ingeniería inversa, lo siguiente debe entenderse como “la lógica de implementación descrita públicamente”, no como una explicación oficial completa.

Primero, el flujo en palabras simples

En una frase: primero mira si usas una dirección API personalizada, luego si esa dirección se parece a un servicio de una lista concreta, después revisa la zona horaria de tu equipo y, finalmente, esconde el resultado en una frase de fecha.

Según el análisis público, la cadena aproximada sería:

  1. Antes de iniciar o enviar una solicitud, Claude Code lee ANTHROPIC_BASE_URL.
  2. Si esa variable no existe, o sigue apuntando a la dirección oficial por defecto, la lógica especial de marcado puede no activarse.
  3. Si apunta a un endpoint personalizado, el cliente analiza la URL y extrae el hostname.
  4. El cliente compara el hostname con listas internas y reglas de palabras clave.
  5. Al mismo tiempo lee la zona horaria local y comprueba si es una zona objetivo como Asia/Shanghai o Asia/Urumqi.
  6. El cliente no añade un campo independiente, sino que modifica la frase de fecha dentro del system prompt.
  7. El servidor recibe la solicitud y lee la marca del entorno del cliente a partir del separador de fecha y el punto de código del apóstrofo.

La parte más enrevesada es el paso 6. No escribe un campo evidente como:

1
2
3
4
{
  "region": "CN",
  "proxyMatched": true
}

En su lugar, mete la información en un texto normal:

1
Today's date is 2026-06-30.

La mayoría de la gente solo ve una fecha. La señal real está en si la fecha usa / o -, y en el apóstrofo casi idéntico dentro de Today's.

En pseudocódigo, la lógica se parece a esto:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
baseUrl = readEnv("ANTHROPIC_BASE_URL")

if baseUrl is empty or baseUrl is official api.anthropic.com:
    send normal system prompt
else:
    hostname = parseHostname(baseUrl)
    domainHit = matchDomainList(hostname)
    labHit = matchAiLabKeywords(hostname)
    timezoneHit = localTimezone in ["Asia/Shanghai", "Asia/Urumqi"]

    dateText = buildDateText()
    dateText = encodeTimezone(dateText, timezoneHit)
    dateText = encodeDomainStatus(dateText, domainHit, labHit)

    send system prompt with dateText

Lo importante no son los nombres exactos de las funciones, sino el orden: leer el entorno local, tomar una decisión local y escribir esa decisión de vuelta en el texto del prompt. El usuario ve una solicitud normal al modelo; el servidor ve una solicitud con estado.

Qué detecta cada paso

Si se descompone el proceso, la información que obtiene cada paso no es muy compleja, pero combinada forma un perfil de entorno bastante claro.

Paso Qué lee el cliente Qué decide Dónde escribe el resultado
Leer variable de entorno ANTHROPIC_BASE_URL Si se usa un API endpoint personalizado Decide si entra en la lógica posterior
Analizar URL hostname A qué tipo de dominio pertenece el endpoint Afecta al punto de código del apostrophe
Comparar listas Sufijos de dominio y palabras clave Si coincide con servicios específicos o palabras clave de laboratorios de IA Afecta al punto de código del apostrophe
Leer zona horaria timezone local Si pertenece a una región objetivo Afecta al separador de fecha
Reescribir prompt Frase de fecha Codifica las decisiones anteriores system prompt

Así que no depende de una sola señal. ANTHROPIC_BASE_URL es solo la entrada; el hostname y la zona horaria sirven para clasificar después, y el system prompt es el lugar donde viaja el resultado.

Punto de activación: ANTHROPIC_BASE_URL

El primer paso mencionado en los análisis públicos es leer la variable de entorno ANTHROPIC_BASE_URL.

Esta variable suele usarse para que Claude Code no solicite directamente el api.anthropic.com oficial, sino un API endpoint personalizado, una pasarela empresarial, un proxy o un servicio relay compatible con la API de Anthropic. Es decir, la variable en sí no es una configuración maliciosa. Muchos equipos usan pasarelas personalizadas por red, cumplimiento, auditoría, autenticación unificada o gestión de costes.

Según los análisis públicos de ingeniería inversa, la lógica relacionada no se activa incondicionalmente para todas las solicitudes. Solo entra en las comprobaciones posteriores después de detectar una API base URL no predeterminada. Ese diseño es importante: primero separa a los usuarios que conectan directamente al servicio oficial de los que usan endpoints personalizados, y luego identifica con más detalle el entorno de estos últimos.

A alto nivel, el proceso puede dividirse en tres capas:

  1. Si ANTHROPIC_BASE_URL está configurado.
  2. Si el hostname de esa URL coincide con una lista de dominios o palabras clave.
  3. Si la zona horaria local pertenece a una región determinada.

Por eso la controversia se concentra en herramientas locales de desarrollo como Claude Code. Se ejecuta en la máquina del usuario y puede leer de forma natural variables de entorno, zona horaria, archivos de configuración y contexto del shell.

Primer paso: extraer el hostname del endpoint personalizado

Si existe ANTHROPIC_BASE_URL, el cliente puede analizarlo como URL y extraer el hostname.

Por ejemplo:

1
https://example-gateway.com/v1

La parte que normalmente participa en la comparación no es la URL completa, sino:

1
example-gateway.com

Esto tiene dos efectos.

Primero, la ruta, el query string y la versión concreta de la API no importan; solo se mira el cuerpo del dominio. Segundo, la lógica de coincidencia puede reutilizar una lista de dominios o palabras clave sin preocuparse de cómo cada proveedor diseña su API path.

En las discusiones públicas se menciona que esta lista no estaría guardada en texto claro dentro del código, sino ofuscada o codificada, y que se decodificaría en tiempo de ejecución antes de comparar. Eso no demuestra por sí solo intención maliciosa, pero sí reduce la posibilidad de que un usuario normal descubra las reglas buscando cadenas.

Segundo paso: comprobar la zona horaria del sistema

Otra señal mencionada repetidamente es la zona horaria del sistema.

Según el análisis público, la lógica de detección presta atención a zonas como:

1
2
Asia/Shanghai
Asia/Urumqi

La zona horaria es una señal sutil. No requiere una solicitud de red ni leer una dirección IP, pero puede reflejar aproximadamente la región del usuario o sus hábitos de uso del sistema. Muchos desarrolladores pueden cambiar la salida de red, pero normalmente no cambian la zona horaria del equipo, porque afecta a calendarios, logs, marcas de tiempo de compilación y uso diario.

Si el cliente solo mirara la IP, el usuario podría estar detrás de un proxy, una salida empresarial o un entorno cloud. Si también mira la zona horaria local, añade otra capa de evaluación del entorno local.

Tercer paso: comparar listas de dominios y palabras clave

Además de la zona horaria, el análisis público menciona dos tipos de coincidencia de hostname:

  • Si coincide con dominios específicos, sufijos de dominio o listas de proveedores.
  • Si contiene palabras clave relacionadas con laboratorios de IA, servicios de modelos o empresas relacionadas.

El objetivo quizá no sea simplemente decidir “si es un usuario chino”, sino clasificar distintos tipos de riesgo: una pasarela personalizada común, un endpoint relacionado con una región, un endpoint relacionado con laboratorios de IA o varias condiciones al mismo tiempo.

Eso explica por qué la codificación posterior necesita varios estados. Si solo se quisiera expresar “coincide/no coincide”, bastaría una marca binaria. La sustitución de caracteres Unicode descrita públicamente permite representar más combinaciones.

Técnica clave: escribir el resultado en el system prompt

La parte más polémica es que el resultado de la detección no se sube como un campo explícito, sino que se codifica dentro de una frase de fecha del system prompt.

Las solicitudes de Claude Code ya incluyen información de sistema como:

1
Today's date is 2026-06-30.

Según el análisis público, el cliente modifica esa frase de dos maneras antes de enviar la solicitud.

La primera es el separador de fecha. Si se detecta una zona horaria objetivo, la fecha puede cambiar de:

1
2026-06-30

a:

1
2026/06/30

La segunda es sustituir el apostrophe en Today's. A simple vista parecen todos apóstrofos, pero sus puntos de código Unicode son distintos. Por ejemplo:

1
2
3
4
'
ʼ
ʹ

En pantalla se ven muy parecidos, pero para un programa son caracteres completamente diferentes. El servidor solo tiene que comprobar el punto de código entre Today y s date is para leer el estado codificado por el cliente.

De forma más intuitiva, se puede entender como una “tabla de señales”:

Apariencia Unicode Significado aproximado
' U+0027 Apostrophe ASCII normal, sin condición específica
U+2019 Coincide con cierta lista de dominios o sufijos
ʼ U+02BC Coincide con palabras clave de laboratorios de IA
ʹ U+02B9 Varias condiciones coinciden al mismo tiempo

Esta tabla no sirve para enseñar a evitar la detección, sino para explicar por qué no es fácil verlo a simple vista: los cuatro caracteres parecen apóstrofos, pero sus puntos de código son distintos. Logs, terminales y fuentes web pueden hacer que la diferencia sea todavía menos evidente.

Por eso mucha gente lo llama prompt steganography: ocultar información dentro de texto de prompt que parece normal.

Por qué esta marca es discreta

Este método es discreto por tres razones principales.

Primero, no necesita una solicitud adicional. En una captura de red no verás un endpoint separado de “subir información del entorno”; la solicitud sigue siendo una llamada normal al modelo.

Segundo, no necesita un campo evidente. Incluso si revisas el JSON, quizá solo veas un system prompt normal. Si no comparas punto por punto los caracteres Unicode, la diferencia del apóstrofo es fácil de pasar por alto.

Tercero, aprovecha que los usuarios prestan poca atención al system prompt. Los desarrolladores suelen mirar su propio prompt, parámetros de herramientas, consumo de tokens y salida del modelo. Rara vez revisan carácter por carácter el contexto de sistema que el cliente inserta automáticamente.

Desde el punto de vista de ingeniería, el mecanismo es inteligente. Desde el punto de vista de confianza, es delicado. Los usuarios autorizan a Claude Code a ejecutarse en una terminal local para leer y escribir código, ejecutar comandos y ayudar en el desarrollo, no para que rasgos del entorno local se codifiquen de forma oculta en las solicitudes.

Cómo puede leerlo el servidor

Si el análisis público es correcto, la lectura en el servidor no es complicada.

Solo necesita comprobar dos cosas al recibir la solicitud:

  1. Si la fecha usa - o /.
  2. Qué carácter Unicode se usa como apostrophe en Today's.

Dicho de forma más cotidiana: el cliente envía un “formulario normal”, pero en el formato de fecha y en la forma del apóstrofo van metidas dos pequeñas notas.

Por ejemplo, una solicitud normal podría verse así:

1
Today's date is 2026-06-30.

Después de coincidir con una zona horaria objetivo, podría convertirse en:

1
Today's date is 2026/06/30.

Después de coincidir con cierto endpoint, el apóstrofo puede pasar a ser otro carácter Unicode. A simple vista aún podría verse como:

1
Today’s date is 2026-06-30.

Pero el programa no lee el mismo '. El servidor no necesita entender toda la frase; solo tiene que extraer los caracteres en dos posiciones para reconstruir el estado de la marca.

Así puede clasificar la solicitud en estados como:

  • no coincide con listas específicas
  • coincide con cierta lista de dominios
  • coincide con palabras clave relacionadas con laboratorios de IA
  • coinciden varias condiciones al mismo tiempo
  • la zona horaria del sistema pertenece a una región específica

En otras palabras, el verdadero “campo de reporte” no se llama region, proxy ni risk_flag. Está oculto en diferencias de caracteres dentro de texto natural del system prompt.

En qué se diferencia del control de riesgo normal

No es raro que un proveedor haga control de riesgo. Abuso de API, reventa de cuentas, destilación de modelos, concurrencia anómala y violaciones de políticas regionales son problemas reales. La cuestión es la transparencia y los límites.

El control de riesgo normal suele ser más fácil de entender: IP de inicio de sesión, región de pago, frecuencia de solicitudes, información del dispositivo, cuenta de organización, patrón de uso de API key. Estas señales también son sensibles, pero los usuarios pueden esperar razonablemente que una plataforma las use para seguridad.

El punto controvertido aquí es distinto: si el cliente realmente codifica la zona horaria local y los resultados de coincidencia de endpoint personalizado dentro del system prompt, el usuario difícilmente lo sabrá por la interfaz del producto, los campos de la solicitud o las release notes. Para una herramienta de desarrollo con permisos de filesystem y shell, eso afecta directamente a la confianza.

Qué deberían vigilar los desarrolladores

La enseñanza no es simplemente “no uses cierta herramienta”, sino volver a mirar los límites de confianza de los agentes locales.

Conviene prestar atención a varias cosas:

  • si el CLI local lee variables de entorno, archivos de configuración, zona horaria, idioma del sistema y otros datos del entorno
  • si el system prompt ensamblado automáticamente puede verse, exportarse y auditarse
  • si el payload final puede inspeccionarse antes de enviar la solicitud
  • si las release notes explican nuevas lógicas de detección, control de riesgo o telemetría
  • si una pasarela empresarial puede registrar y auditar el contenido de solicitudes upstream
  • si la herramienta local ofrece opciones para desactivar telemetría o lectura de entorno sensible

Si una herramienta de programación con IA puede leer y escribir archivos del proyecto, ejecutar comandos shell, acceder a git y leer variables de entorno, en esencia ya se parece a un agente local con altos privilegios. El estándar de transparencia para este tipo de herramientas debería ser más alto que el de una página de chat normal.

Conclusión

Lo que realmente merece discutirse en esta controversia sobre la marca de agua en solicitudes de Claude Code no es si una cuenta fue suspendida, sino cómo un cliente puede codificar información del entorno dentro de una solicitud normal.

Según los análisis públicos de ingeniería inversa, el flujo sería aproximadamente: leer ANTHROPIC_BASE_URL, analizar el hostname, comparar listas de dominios y palabras clave, comprobar la zona horaria del sistema y escribir el resultado en el system prompt mediante el separador de fecha y un apostrophe Unicode. Todo el proceso no necesita solicitudes de red adicionales ni campos explícitos nuevos.

Si esto forma parte del control antiabuso, el proveedor aun así debería explicar los límites con más transparencia. Cuanto más permiso le dan los desarrolladores a un agente local, más necesitan saber qué lee, qué reescribe y qué envía.

Cuanto más potentes se vuelven las herramientas de programación con IA, menos puede resolverse la confianza con un simple “confiemos por defecto”.

记录并分享
Creado con Hugo
Tema Stack diseñado por Jimmy