"¿Tus datos están cifrados?" es la pregunta que aparece en todos los cuestionarios de compliance, DPA, auditoría PCI y conversación con un cliente enterprise. La respuesta casi universal es "sí, totalmente" — y casi universalmente es incompleta.
Cifrado en tránsito (TLS/HTTPS) y cifrado en reposo son dos cosas distintas que protegen contra amenazas distintas. Tener uno no implica tener el otro. Y en WooCommerce específicamente, los defaults cubren el tránsito pero dejan casi todo el resto en claro. El resultado es una tienda que cumple "checkbox SSL" pero tiene su base de datos de clientes accesible al primer compromiso de servidor, al primer backup mal guardado, al primer empleado con acceso filesystem curioso.
Este artículo ordena qué protege qué, audita los puntos donde WooCommerce típicamente falla, y describe cómo cerrar cada uno sin romper la tienda.
Lo que vas a aprender
- Qué protege TLS (cifrado en tránsito) y contra qué amenazas no sirve nada.
- Qué es cifrado en reposo, sus niveles (filesystem, TDE, columna) y el trade-off de cada uno.
- Los 8 puntos donde WooCommerce típicamente deja datos en claro aunque creas lo contrario.
- Cómo auditar si tus backups están realmente cifrados o solo "almacenados en un bucket cifrado".
- Qué hacen (y qué ven) Cloudflare, tu hosting y tu email marketing cuando los datos pasan por ellos.
- Un modelo de defensa por capas: tránsito + reposo + sub-procesadores firmados + rotación de llaves.
Cifrado en tránsito: qué hace y qué no
TLS (antes SSL) es el protocolo que cifra la comunicación entre dos puntos de red. Cuando tu cliente abre tu tienda con HTTPS, el navegador y tu servidor negocian una clave de sesión y todo lo que intercambian va cifrado.
Lo que TLS protege
- Sniffing en red intermedia. Alguien en el mismo WiFi público que tu cliente no ve sus passwords, números de tarjeta ni cookies de sesión.
- Integridad del contenido. Si un intermediario malicioso intenta modificar la respuesta, TLS detecta el cambio y cierra la conexión.
- Autenticación del servidor. El certificado TLS prueba que tu cliente está hablando con tu sitio real, no con un impostor (mitiga phishing y DNS hijacking).
Lo que TLS NO protege
- Nada dentro de tu servidor. En cuanto los datos llegan al servidor, se descifran para procesar y se guardan donde sea que los guardes. Si tu MySQL está en claro, el atacante con SSH ve todo.
- Nada dentro de intermediarios MitM intencionales. Cloudflare, tu CDN con TLS termination, tu WAF en la nube — todos descifran en su extremo. TLS es punto a punto; no es end-to-end salvo que diseñes así.
- Memoria RAM del servidor. Técnicamente los datos viven en claro en RAM mientras PHP los procesa. Es normal y casi inevitable; contra amenazas específicas se usan HSMs o memoria cifrada.
- Logs de aplicación. Si tu PHP loguea el body del request (error, warning, debug), esos logs pueden contener datos sensibles en claro aunque TLS haya sido perfecto.
Configuración mínima de TLS en 2026
- Certificado emitido por CA reconocida (Let's Encrypt es gratis y suficiente para ecommerce chico; DigiCert, Sectigo para enterprise).
- TLS 1.3 habilitado; TLS 1.2 permitido como fallback; TLS 1.0 y 1.1 deshabilitados completamente.
- Cipher suites modernas (AEAD: AES-GCM, ChaCha20-Poly1305); sin RC4, sin 3DES, sin CBC inseguros.
- HSTS con preload (header
Strict-Transport-Security+ inclusión en lista HSTS del navegador). - Redirección obligatoria HTTP → HTTPS a nivel servidor, no solo a nivel WordPress.
- Prueba mensual con SSL Labs — objetivo A+ o A como piso.
Si tu sitio saca B o peor en SSL Labs, arreglalo antes de preocuparte por cifrado en reposo — el problema más grande es el tránsito.
Cifrado en reposo: niveles y cobertura
En reposo significa "cuando el dato está quieto, guardado en algún medio persistente". Hay varios niveles y cada uno protege contra amenazas distintas:
Nivel 1: Cifrado de disco completo (FDE)
El volumen entero del servidor está cifrado. Si alguien roba el disco físico, ve ruido. Común en laptops (BitLocker, FileVault), cada vez más común en servidores (LUKS en Linux, cifrado AWS EBS).
Protege contra: robo físico, disco defectuoso devuelto al fabricante sin borrar, venta de hardware con data residual.
NO protege contra: acceso lógico al servidor. Si el atacante entra por SSH o por web, el volumen está montado y los datos salen en claro.
Nivel 2: Cifrado de base de datos transparente (TDE)
El motor de base de datos cifra los archivos de datos a nivel filesystem y descifra on-the-fly al leer. MySQL (InnoDB tablespace encryption), PostgreSQL (pgcrypto, TDE en Percona), MariaDB.
Protege contra: acceso directo al filesystem de DB sin pasar por el motor, backups físicos del datadir, disco robado.
NO protege contra: queries legítimas del motor. Un atacante con SQL injection ve los datos descifrados porque el motor los descifra para responder la query. Un mysqldump hecho con credenciales válidas sale en claro también.
Nivel 3: Cifrado a nivel columna
Cifrás campos específicos a nivel aplicación antes de guardarlos. La DB ve blobs binarios; la aplicación los descifra con una llave que vive fuera de la DB.
Protege contra: casi todo — incluso SQL injection ve solo blobs inútiles si el atacante no tiene la llave. Backups salen cifrados. Administradores de DB no ven contenido sin acceso a la llave.
Trade-offs: pérdida de queryability (no podés ordenar, filtrar ni indexar por columnas cifradas), overhead de CPU en lecturas, complejidad de gestión de llaves. Útil para campos de alta sensibilidad (DNI, datos financieros, salud), excesivo para email/nombre genérico.
Nivel 4: Cifrado a nivel aplicación con llaves client-side
El cliente (navegador o app móvil) cifra antes de enviar, el servidor nunca ve el claro. Modelo usado por password managers como 1Password o Bitwarden.
Protege contra: todo, incluso compromiso completo del servidor. Si el servidor nunca tuvo la llave, no hay claro que filtrar.
Trade-offs: no aplica a ecommerce típico porque el servidor necesita ver los datos para procesar el pedido. Útil en sectores muy específicos (clínica con historia clínica electrónica, password manager, notas privadas).
Dónde ubicarse razonablemente
Para un WooCommerce típico:
- Piso obligatorio: FDE en el servidor (provisto por AWS/Hetzner/otro por default o 1 click). TDE en MySQL (configurable, overhead bajo).
- Recomendado para sensibles: cifrado a nivel columna para datos fiscales (RFC, NIT), DNI, direcciones precisas de envío si guardás histórico, notas de soporte con datos médicos o financieros.
- Opcional: cifrado client-side si vendés productos de muy alta sensibilidad (joyas, arte, armas legales) donde la privacidad del envío es crítica.
Los 8 puntos donde WooCommerce típicamente deja datos en claro
Auditoría concreta de un WooCommerce estándar que dice "todo cifrado":
Punto 1: Base de datos sin TDE
El default de wp-config.php + MySQL es texto plano. wp_users, wp_usermeta, wp_posts con datos de pedido, wp_wc_order_addresses, wp_comments — todo en claro. Un SELECT * FROM wp_wc_order_addresses te muestra nombres, direcciones, teléfonos y emails.
Fix: activar TDE en MySQL. En hosting administrado muchas veces se activa por ticket; en hosting propio requiere configurar keyring plugin + convertir tablas. Overhead 2-8%, una vez.
Punto 2: Backups en claro
UpdraftPlus, BackupBuddy y Duplicator por default hacen mysqldump y zipean. El ZIP resultante contiene todas las tablas de WooCommerce en claro. Si ese ZIP va a Dropbox, Google Drive, FTP o S3 sin cifrado client-side, cualquiera con acceso al destino ve todo.
Fix: activar cifrado client-side del plugin de backup (UpdraftPlus Premium lo soporta), o cifrar el ZIP con GPG post-dump antes de subir, o usar BlogVault que cifra client-side por default.
Punto 3: wp-config.php con credenciales en claro
El archivo wp-config.php tiene DB_USER, DB_PASSWORD, claves de auth, y si integraste APIs externas, también las API keys. Sale en texto plano en filesystem, accesible por cualquier proceso PHP con permisos de lectura (o sea: todos los plugins).
Fix: permisos 600 estrictos, secretos en variables de entorno cuando el hosting lo permita, rotación periódica.
Punto 4: Logs de aplicación con PII
error_log, logs de debug de WooCommerce (/wp-content/uploads/wc-logs/), logs de plugins como WPForms, NinjaForms o Gravity Forms — muchos incluyen el contenido de los formularios y pedidos cuando hay error. Esos logs están en claro, con permisos accesibles por web server, y son un blindspot clásico.
Fix: auditar periódicamente /wp-content/uploads/wc-logs/, redactar PII antes de loguear, rotar y borrar logs antiguos, bloquear acceso web a directorios de logs.
Punto 5: Emails transaccionales que contienen todo el pedido
Cada email de confirmación que manda WooCommerce contiene nombre completo, dirección, teléfono, items y totales. Esos emails pasan por tu SMTP provider (SendGrid, Mailgun, Amazon SES), por los servidores de email del cliente, y quedan guardados en la caja de entrada indefinidamente.
Fix: usar SMTP con TLS obligatorio (en tránsito); no incluir datos sensibles innecesarios en el email cuando un link al área de cuenta alcanza; firmar contratos con el SMTP provider incluyendo cláusulas de tratamiento de datos.
Punto 6: Caché de página con datos dinámicos
Si tu plugin de caché (WP Rocket, W3 Total Cache, LiteSpeed Cache) cachea páginas autenticadas por error, podés estar guardando en disco la versión renderizada de "Mi cuenta" de un cliente — con su nombre, últimos pedidos y dirección — y servirla a otro usuario.
Fix: auditar configuración del plugin de caché para excluir /mi-cuenta/, /checkout/, /carrito/, cualquier URL con cookie de sesión. Test: loguearte con dos cuentas en dos navegadores y verificar que no hay cross-contamination.
Punto 7: Exports de CSV sin protección
Exportar pedidos a CSV para contabilidad es operación común. El CSV sale a /wp-content/uploads/woocommerce_uploads/ o se descarga directo. Si queda en el servidor en un directorio accesible por web, cualquiera con la URL (o un bot scaneando) lo baja.
Fix: nunca generar exports en carpetas accesibles por web. Usar streams directo al cliente sin escribir en disco, o carpeta fuera de public_html con download autenticado.
Punto 8: Integraciones con terceros que no tenés auditadas
Cada plugin que manda datos afuera (email marketing, chat en vivo, CRM, analytics, inventario) es un sub-procesador. Los datos salen cifrados en tránsito (si el plugin usa HTTPS, lo cual no siempre es obvio) pero una vez en el proveedor están bajo su seguridad, no la tuya.
Fix: auditar cada integración: ¿manda qué datos, con qué frecuencia, a qué endpoint? ¿El proveedor tiene SOC2 o ISO 27001? ¿Hay DPA firmado? Inventariá esto en tu RAT (Registro de Actividades de Tratamiento) porque el regulador pregunta específicamente por sub-procesadores.
¿Querés proteger tu sitio ahora?
Drako es el plugin de seguridad con IA para WordPress. Instalación en 2 minutos, desde $9/mes.
Gestión de llaves: la parte que nadie hace bien
Cifrar sin gestionar bien las llaves es seguridad teatral. Los puntos concretos:
Dónde NO guardar llaves
- En
wp-config.phpdel mismo servidor que tiene los datos cifrados. - En el mismo repositorio Git que tiene el código (
.envcommiteado). - En variables de entorno del mismo host, si un atacante ya tiene acceso al host.
- Hardcodeadas en plugins, temas o snippets.
Dónde SÍ guardar llaves
- Vault de secretos separado (HashiCorp Vault, AWS Secrets Manager, Google Secret Manager, Azure Key Vault). La aplicación consulta la llave en runtime con credenciales cortas.
- HSM (Hardware Security Module) para alta sensibilidad — la llave nunca sale del HSM, solo pedís operaciones criptográficas.
- Envelope encryption: la llave maestra protege llaves de datos. Si rotás la maestra, no tenés que re-cifrar todo — solo re-cifrás las llaves de datos con la nueva maestra. AWS KMS, Google Cloud KMS lo hacen así por default.
Rotación
Las llaves deben rotarse periódicamente. Frecuencias prácticas:
- Llave maestra: 1 vez por año.
- Llaves de datos: cada 90 días.
- Llaves API de servicios externos: cada 90-180 días.
Rotación sin downtime requiere que la aplicación soporte múltiples llaves en paralelo durante la ventana de rollover.
Sub-procesadores: lo que pasa por afuera
Tu cifrado termina donde terminan tus sistemas. Cada sub-procesador ve los datos que les mandás en su infraestructura, bajo su seguridad:
- Hosting provider (AWS, Hetzner, DigitalOcean, hosting WordPress administrado) — ven todo lo que está en disco.
- CDN con TLS termination (Cloudflare proxy, Bunny.net) — ven el tráfico descifrado en edge.
- Pasarela de pagos (Stripe, MercadoPago, Wompi, Payu) — ven datos financieros completos; por eso son el único destino razonable de esos datos.
- SMTP provider (SendGrid, Mailgun, SES) — ven contenido de emails transaccionales.
- Email marketing (Mailchimp, ConvertKit) — ven listas + comportamiento.
- CRM (HubSpot, Pipedrive) — ven todos los datos sincronizados.
- Live chat (Intercom, Zendesk) — ven conversaciones de soporte.
- Analytics (Google Analytics 4, Matomo, Plausible) — ven comportamiento de navegación.
Para cada uno: DPA firmado, inventario documentado, mención explícita en tu aviso de privacidad. Es la parte más aburrida del compliance pero la que el regulador revisa primero cuando llega.
Modelo de defensa por capas
El modelo realista que deberías intentar:
- Tránsito: TLS 1.3 obligatorio, A+ en SSL Labs, HSTS preload, sin downgrade permitido.
- Reposo disco: FDE en servidor (provisto por hosting moderno, verificá que esté activo).
- Reposo base de datos: TDE activo, backup cifrado client-side con llave fuera del servidor.
- Reposo datos sensibles: cifrado a nivel columna para campos críticos (datos fiscales, DNI, historial de salud si aplica).
- Gestión de llaves: llaves en Vault externo, rotación programada, envelope encryption.
- Sub-procesadores: inventariados, DPA firmado, auditados anualmente, declarados en aviso.
- Logs y memoria: logs sin PII, rotación agresiva, memoria cifrada en entornos críticos.
- Auditoría: test de penetración anual, revisión de configuración trimestral, ssl-labs mensual.
Cierre
"Todo cifrado" es respuesta demasiado corta para la realidad de un ecommerce que maneja datos de miles de clientes, pasa por media docena de sub-procesadores y tiene backups escondidos en varios buckets. El cifrado útil es capa por capa: tránsito siempre, reposo disco siempre, reposo DB casi siempre, reposo columna para lo sensible, sub-procesadores con contrato y gestión de llaves fuera del sistema que cifran. Si en cualquier punto de esa cadena hay un eslabón en claro, el atacante que compromete un solo sistema accede a todo lo que ese sistema toca — y con la densidad de datos de un WooCommerce activo, es suficiente para configurar una brecha notificable y una multa evitable.
Preguntas frecuentes
Si tengo HTTPS activado, ¿mis datos están cifrados?
Solo en tránsito entre el navegador del cliente y tu servidor. En cuanto llegan al servidor, se descifran para procesarse y se guardan en la base de datos como texto plano salvo que hayas configurado cifrado explícito en reposo. HTTPS protege el tramo red contra sniffing en WiFi público o ISPs curiosos; no protege nada dentro de tu servidor o base de datos. Un atacante con acceso a tu filesystem ve todo el historial de pedidos en claro aunque HTTPS esté perfecto.
¿WooCommerce cifra los datos por defecto en la base de datos?
No. WooCommerce guarda nombres, emails, direcciones, teléfonos, historial de pedidos, notas de cliente y metadatos en MySQL como texto plano. La única parte tokenizada por default son los datos de tarjeta (PAN completo), que nunca tocan tu base de datos porque la pasarela de pago los maneja. Todo lo demás queda en claro, accesible vía phpMyAdmin, SSH o un backup mal guardado. Si necesitás cifrado a nivel registro, debés configurarlo explícitamente con extensiones o cifrado transparente de la base de datos.
¿Qué es TDE y sirve para WordPress/WooCommerce?
TDE (Transparent Data Encryption) cifra los archivos físicos de la base de datos a nivel filesystem — el motor de DB descifra on-the-fly al leer. MySQL lo soporta desde 5.7.11 con el plugin keyring y MariaDB desde 10.1. Protege contra: robo del disco, acceso directo al filesystem, copia de backups físicos. NO protege contra: SQL injection, acceso legítimo de WordPress a la base, ni backup hecho con mysqldump (sale en claro). TDE es capa necesaria pero no suficiente — útil contra compromiso de infraestructura, inútil contra compromiso de aplicación.
¿Mis backups están cifrados? ¿Cómo lo verifico?
Por default casi nunca. UpdraftPlus, BackupBuddy, Duplicator y la mayoría de plugins guardan backups como ZIP con el dump de MySQL y los archivos del sitio tal cual. Si el backup va a un bucket S3 con server-side encryption (SSE-S3 o SSE-KMS), los archivos están cifrados en el disco de AWS pero AWS tiene la llave — no sos vos. Cifrado real de backup requiere client-side: el plugin cifra el archivo con tu clave antes de subirlo, y la llave nunca sale de tu control. UpdraftPlus Premium y BlogVault tienen esta opción; hay que activarla explícitamente. Para verificar: bajá un backup, descomprimilo, y si ves el SQL legible, no está cifrado client-side.
Si uso Cloudflare, ¿Cloudflare puede leer mis datos?
Si usás Cloudflare con TLS completo (Full Strict), el tráfico va cifrado desde el visitante hasta Cloudflare, Cloudflare lo descifra en su edge, lo vuelve a cifrar y lo manda a tu origen. En esa ventana edge Cloudflare ve todo en claro — URLs completas, cookies, contenido de formularios, passwords de login, datos de checkout. Es técnicamente intermediario. Para aplicaciones sensibles podés usar Cloudflare Enterprise con Keyless SSL (tu clave no va a Cloudflare) o elegir otro CDN sin MitM. Para ecommerce típico, el trade-off acepta que Cloudflare ve los datos a cambio de DDoS protection + cache + WAF — pero debés saberlo y registrarlo como sub-procesador en tu aviso de privacidad.
¿Cifrar la base entera hace lenta la tienda?
Con TDE moderno el overhead es 2-8% típico. Con cifrado a nivel columna (solo campos sensibles con AES-256) el overhead es mayor pero focalizado — si cifrás solo la tabla de pedidos, las páginas de producto siguen volando. El problema práctico no es CPU sino pérdida de queryability: si cifrás el email del cliente a nivel columna, no podés hacer `WHERE email LIKE %'` ni ordenamiento alfabético. Para solucionarlo se usan hashes determinísticos (HMAC del email como índice de búsqueda, email cifrado por separado para recuperación). Es implementable pero requiere diseño, no es flip-switch.