Ir al contenido

Lista de enlaces permitidos y bloqueo de contenido

Tu clave pública está a la vista en el código de tu sitio web, así que cualquiera puede copiarla y llamar directamente a la API. Para un formulario de contacto no pasa nada: el correo siempre te llega a ti. Otra cosa es cuando una plantilla toma su destinatario de los parámetros (una confirmación de suscripción al boletín, una respuesta automática, una confirmación de pedido): quien tenga la clave pública podría enviar tu plantilla, desde tu dominio y con tu imagen de marca, a cualquier dirección, y rellenar los textos y los enlaces. Así es como funciona el phishing.

Por eso la regla de Frontmail es: destinatario dinámico ⇒ contenido bloqueado. Puedes seguir enviando a un destinatario elegido en el navegador, pero quien hace la llamada no puede convertir tu plantilla en un correo de phishing.

Solicitud Bloqueada
clave pública + plantilla cuyo To/CC/BCC usa parámetros (Permitir destinatario dinámico activado) sí
respuesta automática (siempre va a la dirección del formulario) sí: enlaces y campos del remitente
clave privada (tu servidor) no, salvo que la plantilla tenga Permitir solo enlaces a dominios permitidos
clave pública + plantilla con destinatario fijo (formulario de contacto) no: solo se aplica la regla del remitente

Una plantilla con Permitir destinatario dinámico activado pero con direcciones fijas en To/CC/BCC no se bloquea.

  1. CAPTCHA obligatoria. La plantilla debe tener activado Exigir CAPTCHA (Turnstile); de lo contrario, la solicitud falla con 403 dynamic_recipient_requires_captcha. La CAPTCHA usa tus propias claves de Turnstile. Si no puedes usar CAPTCHA, envía la plantilla desde tu servidor con una clave privada.
  2. Remitente fijo. La dirección del remitente, el nombre del remitente y Reply-To no pueden usar parámetros: 403 dynamic_field_not_allowed.
  3. Nada de marcado del llamante y textos cortos. Los parámetros de tipo HTML no se pueden rellenar, y cada valor de texto tiene como máximo 500 caracteres (los parámetros de URL, 2048; si el parámetro tiene una Longitud máx. menor, esa se sigue aplicando): 422 invalid_template_params con details.reason: "content_locked".
  4. Enlaces solo a dominios permitidos (consulta más abajo): 403 link_not_allowed.
  5. Límite por destinatario. Como máximo 5 correos por dirección de destinatario y día (UTC), configurable en Seguridad → Correos por destinatario y día (1–1000). Por encima del límite: 429 rate_limited con details.scope: "recipient". Las respuestas automáticas comparten el contador: por encima del límite no se crea ninguna respuesta automática.

Todas las comprobaciones se hacen antes de gastar un crédito. En las respuestas automáticas, una comprobación fallida marca la respuesta como failed (con el código de error en el historial), el crédito se devuelve y no se envía nada.

Un enlace se permite cuando su dominio:

  • está escrito directamente en la plantilla (HTML, versión de texto o asunto) y no lo genera un marcador de posición. https://acme.com/reset?token={{token}} permite acme.com; {{reset_url}} o https://{{sub}}.acme.com no permiten nada;
  • está en tu lista de orígenes permitidos (Seguridad → Sitios web permitidos);
  • está en Seguridad → Dominios de enlaces permitidos: uno por línea, example.com (exactamente ese host) o *.example.com (subdominios, no el dominio raíz), con las mismas reglas que los orígenes permitidos;
  • es el propio dominio de Frontmail (el pie Enviado con Frontmail del plan Free).

mailto:, tel: y cualquier otro enlace que no sea web (javascript:, data:, …) solo se permiten cuando exactamente el mismo enlace está escrito en la plantilla.

Después del renderizado, Frontmail recopila todas las URL que un cliente de correo podría abrir o convertir en enlace:

  • href, src, srcset, action, formaction, background, poster y otros atributos de URL, también dentro de los comentarios condicionales de Outlook;
  • url() y @import de CSS en los atributos style y en <style>, y <meta http-equiv="refresh">;
  • las URL y los dominios sueltos en el texto HTML, la versión de texto y el asunto: los clientes de correo convierten automáticamente en enlace evil.com/login o www.evil.com, así que también cuentan como enlaces.

Antes de compararlas, las URL se normalizan tal y como las leería un navegador: se decodifican las entidades HTML y los escapes de CSS, se eliminan los caracteres invisibles, \ se trata como /, se resuelve //host relativo al protocolo, se descarta la información de usuario (https://acme.com@evil.com es evil.com), se decodifica la codificación porcentual, se eliminan las mayúsculas y los puntos finales, y los dominios internacionalizados se comparan en punycode: un dominio que imita a otro, como аcme.com con una а cirílica, no coincide con acme.com (el error lo marca con idn: true).

El error solo enumera los dominios problemáticos en details.hosts, nunca las URL completas, que pueden contener tokens.

  • Los dominios sueltos se detectan con una lista de terminaciones conocidas que no son dominios (report.pdf, index.html y Node.js no son enlaces), así que un texto como Mr.Smith puede contar como el dominio mr.smith. Las terminaciones favoritas del phishing que también son dominios reales (.zip, .mov) cuentan siempre.
  • Las direcciones de correo sueltas en el texto (jane@example.com) no se tratan como enlaces.
  • La comprobación se centra en adónde llevan los enlaces, no en el texto que los rodea. En los formularios públicos, mantén los textos cortos y el límite por destinatario bajo.

Activa Permitir solo enlaces a dominios permitidos en los ajustes de la plantilla (Ajustes → Protección) para aplicar la comprobación de enlaces a todas las solicitudes, incluidos los envíos con clave privada. Viene activada por defecto en las plantillas de la galería con destinatario dinámico.

En todas las solicitudes con clave pública, la dirección del remitente de la plantilla no puede venir de los parámetros (de lo contrario, 403 dynamic_field_not_allowed). Un formulario de contacto que pone la dirección del visitante en Reply-To sigue funcionando: ese es su sitio. El editor de plantillas te avisa de todo esto en Comprobaciones.