Funciones de Encoding + Hashing — referencia de Marketing Cloud AMPscript
URLEncode, Base64Encode/Decode, HTMLEncode, el wrapper de tracking RedirectTo, más hashes SHA1/SHA256/SHA512/MD5 y encriptación simétrica. Cada función va con una forma de falla de producción — escape de URL equivocado rompe links de tracking, HTMLEncode faltante abre XSS en CloudPages, MD5 usado como seguridad en vez de como tracking key.
La superficie de encoding y hashing es chica pero cargada: cada link de tracking, cada payload firmado, cada CloudPage form que renderea input de usuario toca una de estas funciones. Las formas de falla son mayormente invisibles — un URLEncode que no escapa + produce un link de tracking que silenciosamente rompe para algunos destinatarios, un HTMLEncode que no se aplicó hace que una CloudPage sea vulnerable a XSS, un MD5 usado como hash de seguridad da una sensación falsa de integridad. Ninguna tira; todas se entregan.
Esta página es el inventario más los patrones que la próxima persona leyendo el código necesita saber antes de cambiar nada.
Sintaxis oficial
Encoding
%%[
/* URLEncode — percent-encode para URLs */
SET @encoded = URLEncode(@rawValue)
SET @encodedForm = URLEncode(@rawValue, 1) /* 2do arg = 1 → form-style (espacio → +) */
SET @encodedUtf8 = URLEncode(@rawValue, 1, 1) /* 3er arg = 1 → modo UTF-8 */
/* Base64 — encoding */
SET @b64 = Base64Encode(@rawValue)
SET @b64Url = Base64Encode(@rawValue, 1) /* variante URL-safe: - y _ en vez de + y / */
SET @b64Utf8 = Base64Encode(@rawValue, 1, 1) /* URL-safe + UTF-8 */
SET @decoded = Base64Decode(@b64)
SET @decodedUrl = Base64Decode(@b64Url, 1) /* tiene que matchear la flag del encode */
/* Encoding de entidades HTML — crítico para renderear input de usuario en CloudPages */
SET @safe = HTMLEncode(@userInput)
/* "<script>" → "<script>" */
]%%
<!-- Renderear input de usuario adentro de HTML — siempre HTMLEncode -->
<p>Buscaste: %%=v(@safe)=%%</p>Wrappers de tracking
%%[
/* RedirectTo — envuelve una URL a través de la capa de redirect + click-tracking de MC.
La URL devuelta registra un evento de click cuando se sigue. */
SET @trackedUrl = RedirectTo(@finalUrl)
]%%
<a href="%%=v(@trackedUrl)=%%">Clic acá</a><!-- BeginImpressionRegion + EndImpressionRegion — trackea impresiones
de un bloque de contenido (solo CloudPages; no se usa en cuerpo de email). -->
%%[ BeginImpressionRegion("hero-promo") ]%%
<div>...contenido del hero...</div>
%%[ EndImpressionRegion() ]%%%%[
/* TreatAsContent — re-parsea un string como AMPscript. Usado cuando AMPscript
está guardado en una columna de DE (templates editables por admin) y se
renderea después. Peligroso: nunca pases input de usuario a TreatAsContent
— template injection. */
SET @templateBody = Lookup("de_email_templates", "Body", "TemplateId", @templateId)
SET @rendered = TreatAsContent(@templateBody)
]%%Hashing
%%[
/* Funciones de hash estándar — output es string hex */
SET @sha1 = SHA1(@payload) /* 40 chars hex */
SET @sha256 = SHA256(@payload) /* 64 chars hex */
SET @sha512 = SHA512(@payload) /* 128 chars hex */
SET @md5 = MD5(@payload) /* 32 chars hex — NO para seguridad */
/* HMAC — hashes keyeados para resistencia a tampering.
La disponibilidad varía por tenant; verificá en tu tenant antes de apoyarte. */
SET @hmacSha256 = HMACSHA256(@payload, @secretKey)
]%%Encriptación simétrica
%%[
/* EncryptSymmetric — usa un algoritmo simétrico de .NET con una key nombrada
guardada al nivel del tenant (Setup → Key Management). El arg keyName
referencia la key del tenant, no el valor de la key en sí — más seguro
que material de key inline. */
SET @cipher = EncryptSymmetric(@plaintext, "AES", "myKeyName", @null, @null, @null, @null)
SET @plain = DecryptSymmetric(@cipher, "AES", "myKeyName", @null, @null, @null, @null)
]%%El set soportado:
| Función | Propósito | Notas |
|---|---|---|
| URLEncode(s [, formStyle [, asUtf8]]) | Percent-encode para URLs | 2do arg = form-style (espacio → +); 3er arg = modo UTF-8 |
| Base64Encode(s [, urlSafe [, asUtf8]]) | Base64 encode | La variante URL-safe usa - y _ |
| Base64Decode(s [, urlSafe [, asUtf8]]) | Base64 decode | Tiene que matchear la flag del encode |
| HTMLEncode(s) | Escapar entidades HTML | La defensa XSS para input de usuario en CloudPages |
| RedirectTo(url) | Envolver URL en el redirect de click-tracking de MC | Devuelve una URL trackeada |
| BeginImpressionRegion(name) / EndImpressionRegion() | Trackear impresiones de un bloque de contenido | Solo CloudPages |
| TreatAsContent(s) | Re-parsear un string como AMPscript | Riesgo de template injection si s es input de usuario |
| SHA1(s) / SHA256(s) / SHA512(s) | Hash criptográfico | Output string hex |
| MD5(s) | Hash legacy | No para seguridad; común para tracking keys |
| HMACSHA256(s, key) (y variantes SHA1/SHA512) | Hash keyeado para resistencia a tampering | Disponibilidad depende del tenant |
| EncryptSymmetric(value, algo, keyName, ...) | Encriptación simétrica con key gestionada por el tenant | Algo: AES; keyName referencia Setup → Key Management |
| DecryptSymmetric(value, algo, keyName, ...) | Desencriptación simétrica | Tiene que matchear exactamente los args del encrypt |
Referencia:
- AMPscript Guide — referencia de funciones (secciones encoding + hashing) ↗
- Salesforce Developer — funciones AMPscript ↗
Lo que sobrevive en producción
URLEncode default vs form-style — elegí el que tu destino espera
El 2do argumento switchea entre dos convenciones de URL encoding:
- Default (sin 2do arg o
0): percent-encodea espacios como%20. Encoding RFC 3986 estándar para componentes de URL. - Form-style (
1): encodea espacios como+. Estándarapplication/x-www-form-urlencoded.
%%[
SET @s = "hello world"
SET @rfc = URLEncode(@s) /* → "hello%20world" */
SET @form = URLEncode(@s, 1) /* → "hello+world" */
]%%Los dos son intercambiables para la mayoría de los contextos browser-decoded, pero algunos sistemas downstream (especialmente APIs viejas y endpoints de tracking) solo aceptan uno. La falla del hand-off: una CloudPage existente usa form-style; un dev nuevo clona la lógica del link a un contexto nuevo sin chequear; el downstream del contexto nuevo rechaza los + como pluses literales; los emails salen con links rotos.
La convención Cleon: usá default (RFC 3986) salvo que el destino requiera form-style explícitamente. Comentá la elección cuando se necesite form-style.
Base64Encode URL-safe vs estándar — + y / rompen query strings
El Base64 estándar usa el alfabeto [A-Z][a-z][0-9]+/. Los caracteres + y / tienen significado especial en URLs (+ = espacio en form encoding, / = separador de path). Un valor Base64 estándar embebido directamente en una query string se transporta mal salvo que el encoder esté seteado a URL-safe.
%%[
SET @raw = "subscriberKey=abc123|action=optout"
/* EN RIESGO — contiene + o / que rompe en una URL */
SET @std = Base64Encode(@raw)
/* "c3Vic2NyaWJlcktleT1hYmMxMjN8YWN0aW9uPW9wdG91dA==" — puede estar bien acá */
/* DURABLE — la variante URL-safe usa - y _ en vez de + y / */
SET @urlSafe = Base64Encode(@raw, 1)
/* El lado del decode tiene que matchear el lado del encode */
SET @backToRaw = Base64Decode(@urlSafe, 1)
]%%La falla del hand-off: el lado del encode usa URL-safe, el lado del decode usa default. Los caracteres + y / que deberían haber sido - y _ se interpretan como los caracteres equivocados, el base64 decode falla en silencio, el payload se vuelve basura. La convención Cleon: cuando entregás un Base64Encode, entregá el Base64Decode que matchea en el mismo cambio, con el mismo valor de flag, y un comentario linkeándolos.
HTMLEncode es la defensa XSS para input de usuario en CloudPages
Cada vez que una CloudPage renderea texto que se originó fuera de Marketing Cloud — un campo de form, un parámetro de URL, un resultado de Lookup que vino de un webhook inbound — pasalo por HTMLEncode antes de outputear. Sin eso, un payload con tags <script> se ejecuta en el browser del destinatario.
%%[
SET @search = RequestParameter("q")
/* PELIGROSO — renderea input crudo; "<script>alert(1)</script>" se ejecuta */
]%%
<p>Buscaste: %%=v(@search)=%%</p>
<!-- vs -->
%%[
SET @search = RequestParameter("q")
SET @safe = HTMLEncode(@search)
/* DURABLE — las entidades están escapadas; "<script>" renderea como texto */
]%%
<p>Buscaste: %%=v(@safe)=%%</p>La regla Cleon: cualquier cosa que viene de afuera de la SQL Activity de audience-build es "input de usuario". Parámetros de URL, submissions de form, payloads de webhook, hasta columnas de DE populadas por un usuario en una CloudPage — todas pasan por HTMLEncode antes de renderearse a HTML. La defensa es envolver en la capa de render, no confiar en saneamiento upstream.
Para contextos de atributo (<a href="...">, <input value="...">), HTMLEncode solo no alcanza — escapá los caracteres de comilla explícitamente y usá URLEncode para valores de href que incluyen cualquier segmento controlado por el usuario.
RedirectTo es el wrapper de tracking subutilizado
RedirectTo envuelve una URL a través de la capa de redirect + click-tracking de MC. La URL devuelta registra un evento de click cuando se sigue; sin eso, el link es invisible para el reporting de MC.
%%[
/* El link funciona sin RedirectTo, pero no se dispara evento de click */
SET @plain = @ctaUrl
/* DURABLE — el click se trackea, reporteable en Email Studio */
SET @tracked = RedirectTo(@ctaUrl)
]%%
<a href="%%=v(@tracked)=%%">Clic acá</a>El comportamiento default del wrapper de links de Email Studio maneja la mayoría de los tags <a> estáticos automáticamente. RedirectTo es para URLs construidas dinámicamente armadas desde variables AMPscript — esas se saltean el wrapping automático y necesitan tracking explícito. La falla del hand-off: un CTA estaba hardcodeado el trimestre pasado (auto-trackeado), se refactoriza a una URL construida con AMPscript para una variante de personalización, las métricas de click caen a cero, y nadie conecta la caída con el refactor por semanas.
TreatAsContent es un riesgo de template injection — nunca sobre input de usuario
TreatAsContent re-parsea un string como AMPscript. Útil para guardar contenido AMPscript-templateado en una columna de DE (templates editables por admin, bloques de email dinámicos) y rendererarlos en send time. Catastrófico si el string fuente viene de input de usuario.
%%[
/* SEGURO — template curado por admin guardado en un DE solo escribible por users trusted */
SET @body = Lookup("de_email_templates", "Body", "TemplateId", @templateId)
SET @rendered = TreatAsContent(@body)
/* PELIGROSO — contenido controlado por el usuario pasado a TreatAsContent
permite al usuario inyectar AMPscript que corre en render time,
lee data de otros destinatarios, hace llamadas Cloud-write, etc. */
SET @userTemplate = RequestParameter("template")
SET @rendered = TreatAsContent(@userTemplate) /* NUNCA */
]%%La regla Cleon: TreatAsContent es whitelist-only. Documentá cada call site con un comentario nombrando la fuente trusted. El code review rechaza cualquier llamada nueva a TreatAsContent que no se traza hasta un DE solo escribible por users trusted (admin UI, SQL Activity, automation interna).
MD5 es para tracking keys, no para seguridad
MD5 está roto criptográficamente y es inapropiado para cualquier uso de integridad o autenticación. Sigue teniendo un uso legítimo en AMPscript: generar identificadores cortos, estables, determinísticos para tracking pixels y keys de analytics.
%%[
/* LEGÍTIMO — MD5 de subscriber + send produce un identificador estable y corto
para tracking cross-system. Sin pretensiones de seguridad. */
SET @trackingKey = MD5(Concat(_subscriberKey, "-", _jobid))
/* NUNCA — MD5 no puede probar que el payload no fue tamperado */
SET @signature = MD5(Concat(@payload, @secret)) /* no es una firma de seguridad */
]%%Para resistencia a tampering, usá HMACSHA256(payload, key) si tu tenant lo soporta. La familia HMAC toma un argumento de key y produce un hash que es verificable solo por alguien que tiene la key. La falla del hand-off: un dev previo usó MD5(payload + secret) como "firma"; un dev nuevo asume que el patrón existente es sólido y entrega más código encima. La torre entera de código no está firmando nada.
Los outputs de hash son strings hex — largo fijo por algoritmo
%%[
SET @s = "hello"
SET @sha256 = SHA256(@s)
/* Siempre 64 caracteres de hex: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 */
/* Útil para columnas de DE de ancho fijo: SHA256 entra en NVARCHAR(64). */
/* Útil para transporte en query-string: hex es URL-safe por default. */
]%%El output de hash es hex por default, no bytes crudos — no hace falta Base64 para transporte. La propiedad de ancho fijo es útil para diseño de schema de DE: una columna que guarda un SHA256 puede ser NVARCHAR(64), sin nulls.
EncryptSymmetric / DecryptSymmetric — el manejo de keys es la parte difícil
Las funciones de encriptación referencian una key gestionada por el tenant guardada en Setup → Key Management, no un string de key inline. El arg keyName busca la key por nombre configurado; el material de key real nunca aparece en tu AMPscript.
%%[
/* El "myKeyName" es el nombre configurado de la key en Setup, NO el valor de la key.
Esto evita material de key inline en columnas de DE o en code reviews. */
SET @cipher = EncryptSymmetric(@pii, "AES", "myKeyName",
@null, @null, @null, @null)
/* Los args del decrypt tienen que matchear exactamente */
SET @plain = DecryptSymmetric(@cipher, "AES", "myKeyName",
@null, @null, @null, @null)
]%%La falla del hand-off: la key se rota en Setup → Key Management; el ciphertext existente en los DEs se vuelve indesencriptable. AMPscript no lleva metadata de versión en los valores encriptados — tenés que trackear la versión de la key en una columna de DE separada para soportar rotación.
La regla Cleon: si vas a EncryptSymmetric, probablemente ya cruzaste a territorio donde AMPscript es la herramienta equivocada. Encriptá afuera de MC, guardá el ciphertext + la versión de key en el DE, renderealo a través de AMPscript solo si hace falta. No conviertas al cuerpo del email en una primitiva criptográfica.
Decisión rápida
Usá URLEncode (default) cuando:
- Construís un path o componente de query string de URL. Usá form-style (
1) solo cuando el destino lo requiere.
Usá la variante URL-safe Base64Encode(s, 1) cuando:
- El valor codificado va en una query string. Matcheá la flag del decode en el lado que recibe.
Usá HTMLEncode cuando:
- Renderás cualquier texto que se originó afuera de la SQL Activity de audience-build. Tratá parámetros de URL, input de form, payloads de webhook, y columnas de DE escritas por CloudPage form como no-trusted.
Usá RedirectTo cuando:
- La URL del link está construida dinámicamente desde AMPscript y necesita tracking de click. Los tags
<a>estáticos en cuerpos de email se trackean automáticamente.
Usá TreatAsContent solo cuando:
- La fuente es una columna de DE solo escribible por users trusted. Whitelist-only. Comentá la fuente trusted en cada call.
Usá SHA256 (o SHA512) cuando:
- Necesitás un fingerprint determinístico de un payload para propósitos no-security (cache keys, deduplicación, tokens de idempotencia).
Usá HMACSHA256(payload, key) cuando:
- Necesitás una firma resistente a tampering. Confirmá el soporte del tenant antes de apoyarte.
Usá MD5 solo cuando:
- Generás identificadores cortos, estables, no-security. Nunca como firma.
Mové la encriptación afuera de MC cuando:
- Cualquier cosa más allá del caso de uso más simple de "obfuscar un valor en tránsito". La encriptación simétrica de AMPscript no tiene el tooling de key-rotation que la crypto de producción necesita.
Relacionado
- Basics — superficie del lenguaje soportada
- Funciones de string —
Concat,Substring, etc. para construir payloads antes de encodear - Funciones de Subscriber + Profile —
_subscriberKeyy_jobidpara construir identificadores estables de tracking - Funciones de Cloud-write — la superficie de mayores stakes donde los payloads firmados importan más
- Gotchas de MC AMPscript — la forma de falla que esta superficie manifiesta más seguido es ruptura silenciosa (link roto, render en blanco, XSS)
- AMPscript de MC: Style Guide — la checklist de disciplina para renders de producción
- MC SSJS — funciones de Encoding — la superficie SSJS hermana para patrones de Base64 + URL encoding
- MC SSJS — funciones de Hashing — la hermana SSJS para patrones de SHA + HMAC
Progreso del catálogo: con esta página, la referencia de AMPscript está completa (8 páginas de referencia + gotchas). Restante: Style Guide (decision-framework) + 3 snippets how-to de debugging. Después de que cierre AMPscript, abre la subcategoría Config.