Most “PrestaShop security” advice is written from the defender’s imagination. A list of things that could go wrong. We wanted the opposite: a measurement of what actually happens to a live PrestaShop store, in the wild, right now. So we instrumented our own fleet and counted.

We run and defend multiple production PrestaShop stores, and over more than a decade we’ve built and maintained a large catalogue of PrestaShop modules. That gave us something most security write-ups don’t have: a set of real, busy storefronts and permission to watch every hostile request hitting them. For six weeks we recorded every malicious request, not only the ones that succeeded, and not only the ones aimed at software we actually run. If a bot probed a module we don’t even have installed, we logged it anyway, because the goal was an honest, complete picture of the pressure a normal store is under.

The total came to about 1.1 million malicious requests from more than 13,300 distinct IP addresses. Here is what the attackers were actually after, and, for every finding, exactly what to do about it.

1.1Mmalicious requests logged
13,300+distinct attacker IPs
~99%automated recon & noise
220k+secret-file download attempts
32khits on one abandoned module
6 wksmeasurement window

How we measured this

We run and defend a fleet of live production PrestaShop stores, and we build and maintain more than a hundred PrestaShop modules. For six weeks we recorded every request that tripped an attack signature at the web-server edge, across multiple live stores, into a single structured database, de-duplicated by attack identity so one scanner hitting a thousand URLs counts as one campaign, not a thousand incidents. Crucially, we logged probes for software we don't even run, so the picture isn't skewed by our own stack. Every figure below is aggregated and fully anonymised: no store, customer, credential, or exploit detail is published.

First truth: about 99% of it is noise

The single most important thing to understand is the shape of the traffic. The overwhelming majority, well over a million requests, is automated reconnaissance: mass scanners walking the internet, firing the same canned payloads at every IP they can reach, indifferent to whether you run PrestaShop, WordPress, or a Java application.

That is reassuring and dangerous at the same time. Reassuring, because almost all of it bounces off a patched, well-configured store. Dangerous, because that wall of noise is exactly where a targeted attempt hides. The genuinely sharp end is real but small, on the order of 34,000 SQL-injection probes and a couple of thousand attempts to run code directly on the server, a thin slice buried inside a million requests of background static. If you are eyeballing raw access logs, you will never reliably spot the one request that matters. That is the whole case for structured detection over “I’ll check the logs if something feels off.”

Here is the same picture broken down by objective.

Attack objectives by volume, owner/infrastructure traffic excluded. Figures rounded.
What they were afterVolumeWhat it really is
Automated reconnaissance & scanning~99%Mass scanners fingerprinting the whole internet, indifferent to what you run
Secret & config file downloads220,000+.env, .git, framework config, credential theft with no exploit needed
One abandoned blog module (LFI)~32,000A single unmaintained third-party module, more than all other module bugs combined
SQL-injection probes~34,000Mostly against old third-party contact-form, newsletter and search add-ons
Wrong-stack exploits (WordPress, Java, ASP.NET)tens of thousandsFired blindly at PHP stores that could never be vulnerable to them
Remote-code execution (RCE) attempts~2,300The genuinely sharp end. The 1% that turns a bug into full control (webshell drops counted separately)

They come for your secrets first

By sheer volume, the loudest single objective wasn’t exploitation at all. It was credential theft by the shovel-load: over 220,000 requests trying to download secret files, .env and its dozen variants (.env.local, .env.production, .env.backup, /api/.env, and on and on), plus .git/config, framework configuration files, and cached credentials.

The logic is brutally efficient. Why write an exploit when a misconfigured server will simply hand over the database password, the payment API key and the mail credentials in a plain-text file? A single leaked .env is often game over. No vulnerability required, just a directory that was never meant to be public but is.

What to do: make absolutely certain your web server refuses to serve dotfiles and config files. These should return 403 or 404 from the edge, not their contents. It is a five-minute change that neutralises the most common objective we recorded:

# Place these ABOVE your generic PHP handler - nginx matches location blocks in order
# Never serve dotfiles (except ACME) or config/secret files
location ~ /\.(?!well-known/) { deny all; }

location ~* \.(env|git|bak|old|dist|sql|log|lock)$ { deny all; }

location ~* /(composer\.(json|lock)|package(-lock)?\.json|yarn\.lock)$ { deny all; }

# PrestaShop config/credential files (all supported versions)
location ~* /(settings\.inc\.php|parameters\.(php|ya?ml))$ { deny all; }
# Block dotfiles and config/secret files
RedirectMatch 404 /\.(?!well-known)

<FilesMatch "\.(env|git|bak|old|dist|sql|log|lock)$">
    Require all denied
</FilesMatch>

<FilesMatch "^(composer\.(json|lock)|package(-lock)?\.json|yarn\.lock)$">
    Require all denied
</FilesMatch>

# PrestaShop config/credential files (all supported versions)
<FilesMatch "^(settings\.inc\.php|parameters\.(php|ya?ml))$">
    Require all denied
</FilesMatch>

Verify it

From outside the server, request /.env and /.git/config over HTTPS. You want a 403 or 404, if you get any file contents, or even an empty 200, fix it before anything else on this list.

The #1 targeted component: an abandoned module

When we filtered down to attacks aimed at PrestaShop specifically, one target dwarfed everything else: a local file inclusion flaw in an old, no-longer-maintained blog module, roughly 32,000 attempts, more than every other module vulnerability combined.

This is the pattern that quietly wrecks stores. It is almost never core PrestaShop that lets attackers in. It is the third-party module you installed three years ago, stopped updating, and forgot you had. Attackers maintain curated lists of these, module name, vulnerable path, ready-made exploit, and spray them across the entire internet on a loop.

Further down the list were the usual suspects: SQL-injection probes against contact-form and newsletter modules, a known vulnerability in a wishlist module, and a handful of slider and search add-ons. All third-party. All the kind of thing that accumulates in a store over the years and then sits there, unpatched, long after anyone remembers installing it.

What to do: inventory your modules and delete the ones you don’t use. An unused-but-installed module is pure attack surface with zero benefit. Patch the ones you keep, and if the developer has vanished, replace the module rather than hoping. If you’re stuck on a version you can’t safely upgrade, our guide to hardening a store you can’t upgrade walks through virtually patching exactly this kind of hole.

The break-in kit: webshells and backdoors

Past the recon and the secret-hunting sits the sharp end. Attackers repeatedly tried to drop or locate webshells. The tools that turn a single vulnerability into full remote control. The filenames are almost a signature in themselves: adminer.php, alfa.php, wso.php, stray phpinfo probes, and database-manager scripts left behind by a previous compromise.

We also caught something more pointed than generic scanning. When one store in a group is compromised, attackers take the exact payload that worked there and spray it at every related store they can find, betting the same backdoor is still sitting on another one. Persistence pays: a backdoor buried in a rarely-inspected file can survive multiple superficial “cleanups” and keep re-infecting a store for weeks. If you once cleaned a compromise by only removing the visible malicious JavaScript and it came back, this is why, we walked through exactly that failure in our anatomy of a Magecart-style skimmer.

What to do: deny PHP execution in every directory that should only ever hold uploads, images, cache or tools. If a bot manages to write shell.php into your image folder, the difference between a bad day and a full breach is simply whether the server will run it:

# Put this ABOVE your existing "location ~ \.php$" block - nginx is first-match-wins
# A bot that writes shell.php into an image folder must never get it executed
location ~* ^/(img|upload|uploads|cache|var|download)/.*\.(php|phar|phtml|php[0-9])$ {
    deny all;
}
# Drop this .htaccess inside an uploads folder: turn PHP off for the whole tree
<FilesMatch "\.(php|phar|phtml|php[0-9])$">
    Require all denied
</FilesMatch>

After any suspected compromise, assume persistence

Removing the visible symptom is not remediation. Hunt for executable files in writable paths, rotate every credential that lived in a readable config file, and rebuild from a known-clean backup rather than cleaning in place.

They don’t even check what you’re running

A telling illustration of how automated all of this is: we logged tens of thousands of exploit attempts aimed at completely different technology stacks, Java and JSF payloads, WordPress plugin exploits, ASP.NET tricks. All fired blindly at PHP stores that could never be vulnerable to them.

The takeaway isn’t “ha, they missed.” It is the opposite: you are being attacked constantly, by attackers who neither know nor care what you run. You don’t have to be a target to be a victim. You only have to be reachable and out of date.

Check your own store right now

Reading about it is one thing; here are four checks you can run against your own store in the next five minutes. They map directly to what the attackers above are hunting for.

1. Are your secrets actually reachable? From your own machine, ask for the files the scanners ask for. Every line should come back 403 or 404, never 200 with contents:

# From your own machine: 403/404 = safe, 200 = exposed, 000 or 3xx = check by hand
for f in .env .git/config app/config/parameters.php composer.json; do
  printf '%s -> ' "$f"
  curl -s -o /dev/null --connect-timeout 5 --max-time 15 -w '%{http_code}\n' "https://your-store.com/$f"
done

2. Is there PHP hiding where only assets belong? Over SSH, from your shop root, look for executable files in folders that should only ever hold uploads, images or downloads. On a clean store this prints nothing:

# PHP hiding in folders that should only hold assets (a clean store prints nothing)
find img upload uploads download -type f \
  \( -iname '*.php' -o -iname '*.php[0-9]' -o -iname '*.phtml' -o -iname '*.phar' \) \
  ! -iname index.php 2>/dev/null

3. What changed recently? A freshly-dropped backdoor is a recently-modified PHP file you didn’t touch. List the last week’s changes and eyeball anything unfamiliar:

# PHP changed in the last 7 days, cache excluded (GNU/Linux find) - review anything unfamiliar
find . \( -path ./var/cache -o -path ./cache \) -prune -o \
  -type f -iname '*.php' -mtime -7 -printf '%TY-%Tm-%Td  %p\n' | sort

4. Who can log into your back office? Every account is a key to the front door. Investigate any employee you don’t recognise, and any that hasn’t logged in for months (run it from phpMyAdmin or the mysql client):

-- Back-office accounts: investigate any you do not recognise
-- Run in phpMyAdmin or the mysql client; change the ps_ prefix if yours differs
SELECT id_employee, email, active, last_connection_date
FROM ps_employee
ORDER BY last_connection_date DESC;

Prefer a one-click check?

We turned these same checks into tooling. Our free, open-source Security Scan probes your store for exactly these exposures, exposed config and backup files, stray PHP in your asset folders, modules with known CVEs, debug mode and weak hardening, and hands you a prioritised report, at no cost. For ongoing protection, Security Revolution adds a request firewall, rate limiting, security headers, file-change monitoring and vulnerability scanning, all from your back office. And if you’d rather hand the whole thing off, our Security & Hardening Audit is a done-for-you review by our team.

What we actually do on our own stores

Because these are our storefronts too, the defensive list above isn’t theoretical. On the stores in this study we block dotfiles and config files at the edge, deny PHP execution across every writable path, keep a deliberately small module footprint and remove anything unused, enforce two-factor authentication on the admin, and sit the whole thing behind an edge layer that rate-limits scanners and drops obvious injection payloads. And we keep the recorder running, the same request-level logging that produced this article, so a genuinely targeted attempt surfaces instead of drowning in the 99% of noise. None of it is exotic. All of it is boring, and boring is what works.

  • Block secret files at the edge. .env, .git, composer.json and config files must return 403/404, never their contents.
  • Prune your modules. Delete everything you don't use; an unused module is pure attack surface.
  • Patch or replace what you keep. Especially third-party blog, slider, form and search add-ons.
  • Deny PHP in writable folders. Uploads, images, cache and tmp should never execute code.
  • Lock the admin login. Strong, unique credentials and two-factor authentication.
  • Stay on a supported version. An end-of-life platform ships with a permanent set of known keys.
  • Put detection between you and the noise so the 1% that matters can't hide in the 99% that doesn't.

Frequently asked questions

Is PrestaShop secure?

Core PrestaShop is actively maintained and rarely the way in. In our data, almost nothing targeted core, the successful-looking attacks aim at third-party modules, misconfigured servers that leak secret files, and end-of-life installs. A patched, well-configured PrestaShop store on a current version is a hard target. A neglected one is not.

How do I know if my store has already been compromised?

Look for PHP files in directories that should only hold images or uploads, unexpected admin employees, modified .htaccess or index.php files, and unfamiliar scheduled tasks. A backdoor commonly survives a "cleanup" that only removed visible malicious JavaScript, if an infection keeps coming back, an executable file is still on disk somewhere. For a structured self-check, our guide to the warning signs a store needs a security audit is a good next step.

Which modules are the most dangerous?

Any third-party module you no longer update, especially older blog, slider, contact-form, newsletter, wishlist and search add-ons, which have well-known public exploits. The single most-attacked component in our fleet was one abandoned blog module. If the developer has disappeared, treat the module as a liability and replace it.

Do I need Cloudflare or a WAF?

An edge layer that can block dotfile requests, rate-limit scanners and filter obvious injection payloads absorbs a large share of this noise before it reaches PHP. It is not a substitute for patching and removing unused modules, but it meaningfully lowers the pressure and buys you time.

I'm on an old PrestaShop version I can't safely upgrade. What now?

Reduce attack surface aggressively: remove every unused module, block secret files and PHP execution in asset folders at the server, and virtually patch known holes at the edge. Our guide to hardening a store you can't upgrade covers this in detail.

How often is a normal store actually attacked?

Constantly. Across our fleet that was roughly a million malicious requests in six weeks. The overwhelming majority is automated and harmless against a maintained store, but it never stops, and it only takes one neglected door.

The bottom line

Strip away the volume and the picture is simple. The attacks that succeed almost never rely on some exotic zero-day. They rely on the boring stuff: a secret file left readable, an unpatched or abandoned third-party module, a directory that will execute an uploaded PHP file, an admin login with a weak or reused password, an out-of-date platform. None of these are hard to fix. All of them are things a maintained store gets right and a neglected one doesn’t. The attackers have automated the search for neglect, a million times over in six weeks. The only real defence is to not be neglected: patch, prune, lock the obvious doors, and put real detection between you and that wall of noise.

Written by the mypresta.rocks team. We have built PrestaShop modules for over a decade and we run and defend a fleet of live production stores across several countries, the same stores whose logs produced the data above. This article reports what we actually see and what we actually do about it. Everything here is built to work across PrestaShop 1.6, 1.7, 8.x and 9.x. Data window: roughly six weeks to July 2026, anonymised.

Methodology note: figures are aggregated from request-level attack logging across multiple live production stores over a roughly six-week window ending July 2026. All data is anonymised; no store, customer, or credential details are included, and no exploit specifics are published.

Share this post:
David Miller

David Miller

Founder, mypresta.rocks

David Miller is a PrestaShop specialist with over a decade of hands-on experience and the founder of mypresta.rocks, a software studio in Tychy, Poland. He builds and maintains a catalogue of 152 PrestaShop modules, including 21 "Revolution" suites spanning SEO, checkout, security, performance, marketing, search, support, and warehouse operations, that improve real stores every day, all tested against PrestaShop 1.7.8, 8.x, and 9.x. He also acts as caretaker for production stores turning over millions in annual sales, so his work is judged on live revenue, not demos. His experience runs the full breadth of ecommerce, performance, security, SEO, and marketing, and reaches beyond PrestaShop to WooCommerce, Shopify, and custom-built systems. On the blog he writes about the code-aware side of PrestaShop: what the platform really does under the hood, what breaks in production, and which fixes hold up.

Comments

No comments yet. Be the first!
Enjoyed this article?

Get our latest tips, guides and module updates delivered to your inbox.

You may unsubscribe at any moment. For that purpose, please find our contact info in the legal notice.

Loading...
Back to top