Ataques SQL a los filtros de PrestaShop: qué para un .htaccess
En septiembre de 2026 varias tiendas recibieron a la vez intentos de inyección SQL en la URL. Una regla .htaccess genérica bloqueaba URLs buenas y dejaba pasar al atacante; unas reglas más precisas, sacadas de los intentos reales, sí los frenaron. Te contamos por qué y dónde está el arreglo de verdad.
A mediados de septiembre de 2026, Gustavo, de la comunidad, empezó a recibir de varios clientes el mismo aviso de inyección SQL. Todo apuntaba a un fallo recién descubierto en un módulo de una plantilla y a alguien probándolo en todas las tiendas PrestaShop que encontraba. En el grupo se compartieron reglas de .htaccess para pararlo. Respuesta corta: una regla genérica no sirve; una regla hecha con los intentos reales ayuda mientras actualizas el módulo vulnerable, que es el arreglo de verdad.
La regla rápida y por qué falló
La primera propuesta fue la típica: bloquear cualquier petición cuya cadena de consulta contenga cosas como select ... from, union ... select, concat(, sleep( o or 1=1.
Rekire la probó y vio dos problemas:
- Bloqueaba URLs legítimas. Dejaban de funcionar las facetas, las estadísticas, los listados del back-office y el filtro de transportistas.
- No bloqueaba al atacante. Los intentos llegaban codificados, por ejemplo
AND SL%45EP(3), donde%45es la letra E. En Apache,%{QUERY_STRING}llega sin decodificar, así quesleep(no aparece nunca tal cual y la regla no salta.
Las reglas que sí frenaron los intentos
Gustavo tenía un módulo que registraba cada intento. Le pasó todas las inyecciones capturadas a ChatGPT y le pidió reglas que casaran con ellas. El resultado, con los comentarios en castellano:
<IfModule mod_rewrite.c>
RewriteEngine On
# Comentarios ejecutables de MySQL (/*!), también codificados
RewriteCond %{QUERY_STRING} (/\*!|%2f%2a%21|%252f%252a%2521) [NC]
RewriteRule ^ - [F,L]
# GTID_SUBSET / GTID_SUBTRACT
RewriteCond %{QUERY_STRING} (GTID_SUBSET|GTID_SUBTRACT) [NC]
RewriteRule ^ - [F,L]
# UNION SELECT con espacios codificados
RewriteCond %{QUERY_STRING} (UNION(%20|%2b|\+)+(ALL(%20|%2b|\+)+)?SELECT) [NC]
RewriteRule ^ - [F,L]
# SELECT, SLEEP y BENCHMARK
RewriteCond %{QUERY_STRING} (SELECT(%20|%2b|\+)|SLEEP(%20|%2b|\+)*\(|BENCHMARK(%20|%2b|\+)*\() [NC]
RewriteRule ^ - [F,L]
</IfModule>A las pocas horas su módulo dejó de detectar intentos: se cortaban antes de llegar a PrestaShop.
select+, y eso incluye a un cliente que busque «select» en tu buscador. Y fíjate en que tampoco casa con SL%45EP(: funcionaron porque los intentos de esta oleada tenían otras huellas, no porque cubran todos los casos.Dónde ponerlas
- En el
.htaccessde la raíz, antes de las reglas de PrestaShop y fuera del bloque que genera PrestaShop, para que no se pierdan al guardar las opciones de URL amigables. - Si tu servidor tiene un cortafuegos de aplicación (ModSecurity o similar), es mejor sitio: decodifica las peticiones antes de analizarlas y no depende de que acertemos con cada codificación.
El arreglo de verdad
Un .htaccess compra tiempo. Lo que cierra el agujero es localizar el módulo vulnerable y actualizarlo (o quitarlo si no se usa). Para encontrarlo:
- Mira en los registros del servidor a qué URL iban los intentos: el controlador o el parámetro te dirá qué módulo los recibe (en esta oleada, un fichero AJAX del módulo de menú de una plantilla).
- Pregunta al desarrollador de tu plantilla si ha publicado una versión corregida.
- Revisa que no se hayan creado empleados nuevos ni cambiado contraseñas: es lo que se suele buscar con una inyección en una tienda.
Y ten algo que te avise. En este caso el aviso llegó porque las tiendas tenían un módulo que vigilaba las peticiones; sin él, la primera señal habría sido un administrador falso. En Rekire usamos el módulo de alertas de seguridad por Telegram, que avisa si aparece un empleado nuevo, cambia la configuración de pago o se instala un módulo, y revisamos tiendas atacadas dentro de un bono de horas.
Esto salió en @PrestashopEsp, la mayor comunidad PrestaShop de España en Telegram. Ver la conversación