Sin impuesto Con impuesto

Bloquear la ejecución de PHP en modules/ con .htaccess (PrestaShop 1.7 y 8)

En PrestaShop 8 y anteriores cualquier fichero .php dentro de modules/ se puede pedir por URL. PrestaShop 9 ya lo deniega de serie. Te explicamos cómo aplicar esa protección en tu tienda, cómo dejar excepciones y qué otras carpetas conviene cerrar.

Equipo Rekire
Actualizado: 10/10/2026 11
Bloquear la ejecución de PHP en modules/ con .htaccess (PrestaShop 1.7 y 8)
Compartir:

Una de las mejoras de seguridad menos comentadas de PrestaShop 9 está en un fichero de una docena de líneas: el .htaccess que trae de serie la carpeta modules/. Con él, Apache contesta 403 a cualquier petición directa a un .php de un módulo, antes de que PHP llegue a arrancar.

En PrestaShop 1.7 y 8 ese fichero no existe. Cualquier .php que haya dentro de modules/, sea de un módulo instalado, de uno desinstalado o de una puerta trasera, se puede pedir por URL y se ejecuta. Este artículo explica cómo llevar esa protección a tu tienda sin romper nada.

Por qué importa

Casi todo lo que hace un módulo moderno pasa por el despachador de PrestaShop: los controladores front se piden como index.php?fc=module&module=nombre&controller=accion (o su URL amigable), y los de administración van por el back-office. Ninguno de esos caminos necesita pedir un .php de modules/ directamente.

Lo que sí se pide directamente son:

  • Ficheros antiguos de módulos viejos: ajax.php, validation.php, scripts de cron o de importación que arrancan PrestaShop por su cuenta. Algunos tienen vulnerabilidades conocidas.
  • Ficheros de módulos huérfanos, que siguen en disco aunque el módulo se haya desinstalado.
  • Puertas traseras dejadas en la carpeta de un módulo, a menudo con un nombre que parece de toda la vida.

Denegar los .php directos cierra de golpe las tres cosas. Lo que queda abierto es solo lo que pasa por el despachador, que es mucho más fácil de revisar.

Qué hace exactamente PrestaShop 9

El fichero de serie usa un FilesMatch que deniega por extensión, con las directivas de Apache 2.2 y de Apache 2.4. Deniega .php y también otros ficheros que no deberían servirse nunca desde ahí: .log, .txt, .lock, .json, .yml, .yaml, .tpl, .twig, el config.xml de cada módulo y sus variantes por idioma. Los CSS, JavaScript e imágenes de los módulos se siguen sirviendo con normalidad.

Cómo aplicarlo en PrestaShop 1.7 y 8

  1. Haz una lista de lo que se pide directamente. Antes de cerrar, revisa los registros de acceso del servidor de las últimas semanas buscando peticiones a /modules/ que acaben en .php y respondan 200. Esa es la lista de lo que podrías romper.
  2. Clasifica cada una. Retornos de pasarelas de pago, crons programados en el panel, llamadas Ajax de algún módulo antiguo. Cada una es o una excepción justificada o algo que conviene sustituir.
  3. Crea el fichero modules/.htaccess con una denegación de los .php y de las extensiones de configuración, a imagen del de PrestaShop 9. En Apache 2.4 la regla esencial es <FilesMatch "\.(php|phtml|phar|php[0-9])$"> Require all denied </FilesMatch>. Incluir phtml, phar y las variantes numeradas evita que se cuele un fichero con otra extensión que el servidor también ejecute.
  4. Añade las excepciones en la carpeta de cada módulo, no en la general. Por ejemplo, en modules/mipasarela/.htaccess: <Files "notificacion.php"> Require all granted </Files>. Así la excepción vale solo para ese fichero de ese módulo, y no para cualquier fichero que se llame igual en otra carpeta.
  5. Comprueba con peticiones reales. Pide un .php cualquiera de un módulo (debe dar 403), pide el de la excepción (debe responder) y haz un pedido de prueba con cada método de pago.
  6. Revisa los crons. Si un cron del panel llamaba a modules/x/cron.php, ahora fallará sin avisar. Cámbialo por la URL del controlador del módulo si la tiene, o déjalo como excepción.
Las excepciones son deuda. Cada fichero que dejas abierto es un punto de entrada que hay que vigilar. Si un módulo necesita muchas, es una señal de que es antiguo: busca una versión que use controladores o un sustituto. Cuando migres a PrestaShop 9 te encontrarás el mismo problema, así que mejor resolverlo ahora.

Limitaciones que conviene conocer

  • No protege los controladores front. Un controllers/front/ se sirve a través de index.php, así que el .htaccess de modules/ no lo tapa. Si un módulo instalado tiene un controlador vulnerable, sigue siendo vulnerable. Para eso no hay atajo: actualizar o retirar el módulo.
  • Nginx ignora los .htaccess. Si tu servidor es Nginx puro, la denegación se hace con un bloque location en la configuración del servidor, que normalmente toca tu hosting.
  • Depende de que el servidor lea los .htaccess (directiva AllowOverride). Compruébalo pidiendo un .php después de crear el fichero; no lo des por hecho.
  • Un atacante con escritura puede borrarlo. Si alguien puede escribir en modules/, puede quitar el .htaccess. Que desaparezca no tiene ninguna causa legítima, así que vigilar su presencia es en sí una alarma útil.

Las otras carpetas: upload/, img/, var/

upload/ y download/

Ahí van los ficheros que suben los clientes en productos personalizables y los productos descargables. PrestaShop los sirve a través de un controlador, no por acceso directo. En PrestaShop 9, download/ deniega todo y upload/ deniega los ficheros con el nombre interno que les da PrestaShop. Ninguna de las dos debería contener nunca un .php, así que añadir una denegación de PHP en ellas es seguro. Si además tu tienda no sirve nada de upload/ por URL directa, puedes denegarlo todo, pero compruébalo antes.

img/

En PrestaShop 9 deniega todo salvo las extensiones de imagen, vídeo, PDF e iconos. En versiones anteriores, revisa qué trae tu img/.htaccess: puede tener reglas propias, así que añade la denegación de PHP al final, sin sustituir lo que hay. Y cuando regeneres el .htaccess de la raíz desde el back-office, verifica después que tus bloques siguen donde los dejaste.

var/ y cache/

Desde 1.7, var/ trae una denegación total. Comprueba que el fichero sigue ahí: un var/logs accesible filtra rutas, errores y a veces datos de clientes. En tiendas 1.6, la carpeta equivalente es cache/, y no debe servir PHP.

La raíz

Revisa también que no haya copias de seguridad (.zip, .sql, .tar.gz) ni registros de errores del hosting accesibles en la raíz. Un volcado de base de datos descargable es peor que cualquier shell.

Cómo resolverlo en PrestaShop

RKR Security Alert tiene un panel de blindaje de carpetas de datos que comprueba que el .htaccess de upload/, download/, img/ y otras carpetas no solo existe, sino que bloquea de verdad la ejecución, y avisa si aparece algo ejecutable donde solo debería haber datos. Puede escribir el bloque de denegación por ti, añadiéndolo al final del fichero existente y guardando una copia. Para modules/, mira qué extensiones deniega realmente el .htaccess y lo cruza con los puntos de entrada que encuentra, y cada hallazgo del escáner dice si se alcanza por URL o está cerrado. Si prefieres no tocarlo tú, con un bono de horas de soporte de Rekire revisamos los registros, definimos las excepciones necesarias y lo probamos con pedidos reales.

Cargando...
Cookies
Volver arriba