Facundo Cornejo.
Volver a proyectos

Case study

Rodak — Rescate, seguridad y migración de un e-commerce

Una tienda WooCommerce con 1.186 pedidos reales que venía de un compromiso de seguridad. El cliente preguntó si el backup servía, y lo contesté con un ensayo real, no con un "debería andar".

Rediseno en curso, proximamente
WordPressWooCommerceMySQLWP-CLIDockerBash
Rodak — Rescate, seguridad y migración de un e-commerce

Contexto

Rodak es una mueblería que vende online. Me contrataron para reposicionar la marca y construir un configurador de escritorios, pero al abrir el sitio apareció otra cosa primero: una instalación comprometida, sobre hosting compartido con un MySQL viejo, y con la tienda facturando. No se podía rehacer de cero ni apagar: había que arreglarlo en movimiento.

Problema

Antes de cualquier migración el cliente hizo la pregunta correcta: con el backup que tenemos, ¿estás 100% seguro de que en otro servidor podemos desplegar la misma página, idéntica? Esa pregunta no se contesta leyendo un archivo. Un backup no verificado no es un backup: es un archivo grande.

Cómo lo resolví

  • Levanté un clon aislado del servidor con tres capas de protección — autenticación básica, cuarentena de red y noindex — para poder trabajar con datos reales sin exponer nada.
  • Restauré el backup completo, en 14 partes, del lado del servidor, y verifiqué el SHA-256 de las 14 antes de importar nada.
  • Definí gates numéricos ANTES de empezar y después expliqué cada delta: 144/144 tablas importadas, 1.186 pedidos = 1.181 previos + 5 nuevos con sus fechas, 322 variaciones exactas, 1.006 archivos de medios, 20.310 archivos de plugins contra 20.310.
  • El smoke test lleva controles positivos y negativos: home y tienda responden 200, una URL inventada responde 404, y hay 0 referencias al dominio viejo — con un control positivo de 176 coincidencias que demuestra que la búsqueda funcionaba.
  • Para la seguridad armé un ledger donde cada componente solo se cierra con un estado terminal: corregido, eliminado con ruta verificada, o excepción escrita del dueño. "El scanner no lo detecta" no es un estado.
  • Crucé las CVEs de cada componente contra fuentes públicas y dejé anotada la limitación: una de las APIs que quería usar como segunda fuente independiente fue retirada, así que el cruce quedó con una sola fuente y eso está declarado, no escondido.

Mi rol

Auditoría, respuesta al incidente, plan y ejecución del backup y del ensayo de restore, y la comunicación con el cliente. Buena parte del trabajo fue traducir todo esto a mensajes que el dueño pudiera leer sin ser técnico, sin bajarle el rigor a lo que había abajo.

Resultado

El ensayo dio verde en todos los gates: la migración a otro servidor quedó probada, no prometida. Además apareció algo que nadie estaba buscando — una limpieza previa había borrado 20 usuarios, incluida la cuenta de administración del hosting — y lo levanté con la aritmética exacta que lo demostraba. Ese hallazgo salió del ensayo; sin ensayo, se descubría durante la migración real.

Aprendizajes

  • Un backup se verifica por consistencia, contando filas restauradas, no por la existencia del archivo.
  • Todo test necesita un control positivo. "0 referencias al dominio viejo" no prueba nada si la búsqueda estaba rota: el control de 176 coincidencias es lo que le da valor a ese 0.
  • Declarar las limitaciones de una auditoría la hace más creíble, no menos.
  • Frente a un cliente, un ensayo reproducible vale más que cualquier garantía verbal.