The worst moment to figure out your incident-response plan is at 2am, staring at a customer email that says "your checkout charged my card twice and now I'm getting phishing texts." If you run a PrestaShop store long enough, there's a real chance you'll face a compromise — small and mid-size shops get hit constantly, not because they're singled out but because automated scanners spray known PrestaShop and module exploits across the whole web and ring whatever door is unlocked. This guide is the runbook for after the alarm goes off: a calm, ordered sequence of what to check, what to preserve, and what PrestaShop-specific places the attacker has almost certainly touched. It is deliberately not a prevention guide — if you're here before anything has gone wrong, start with the PrestaShop security hardening checklist instead.
Read this once now, while nothing is on fire. The single biggest predictor of a clean recovery is that you knew the order of operations before you needed it.
Reviewed June 2026 against current PrestaShop 1.6, 1.7, 8 and 9 file and database layouts, and the GDPR 72-hour breach-notification rule in force at the time of writing.
Before you touch anything: preserve the evidence

A magnifying glass passes over a grid of glowing file and folder icons, a few highlighted in orange.
If you have shell access, copy the files, database and logs before you delete anything. Adjust the database name and paths to your host.
#!/usr/bin/env bash
set -euo pipefail
stamp=$(date +%F-%H%M%S)
case_dir="/root/prestashop-incident-$stamp"
mkdir -p "$case_dir"
tar --xattrs --acls -czf "$case_dir/files.tgz" /var/www/html
mysqldump --single-transaction --routines --triggers prestashop > "$case_dir/database.sql"
cp -a /var/log/nginx /var/log/apache2 /var/log/php* "$case_dir/" 2>/dev/null || true
sha256sum "$case_dir"/* > "$case_dir/SHA256SUMS"
chmod -R go-rwx "$case_dir
The instinct is to log into the back office and start deleting suspicious files. Resist it. The moment you start changing things, you destroy the trail that tells you how they got in — and if you don't find the entry point, you'll get re-compromised within days. Your first action is to copy, not clean.
Take a full snapshot before any remediation:
- The whole web root — your PrestaShop directory, including hidden files (.htaccess, .user.ini). Attackers love these because few people audit them.
- A database dump — mysqldump the full database. The injection often lives in the database, not just on disk (see below).
- The logs — web server access/error logs (/var/log/nginx/ or /var/log/apache2/), PHP-FPM logs, and PrestaShop's own logs under var/logs/ (PS 1.7+) or log/ (PS 1.6). Logs rotate and disappear; grab them first.
Store that snapshot somewhere the attacker can't reach — your laptop or a fresh storage bucket, not a second folder on the same compromised server. This snapshot is what your host's abuse team, a forensic professional, or a cyber-insurance claim will ask for, and it's the only way to reconstruct a timeline later.
Contain the bleeding without destroying the scene
Containment and forensics pull in opposite directions: you want to stop the damage, but pulling the plug can wipe volatile evidence (active sessions, attacker processes). The balance for a typical store: take the storefront offline to customers, but keep the server itself running so you can investigate.
PrestaShop has maintenance mode built in. In the back office go to Shop Parameters → General → Maintenance (PS 1.7/8/9) and disable the shop, then add your own IP to the Maintenance IP field so you can keep working while customers see a holding page. The underlying flags are PS_SHOP_ENABLE and PS_MAINTENANCE_IP in the ps_configuration table — useful if the back office itself is locked or defaced and you need to flip it straight in the database.
If payment data may be in play, maintenance mode is not enough — and don't go hunting through files first. Two calls take priority over everything technical:
- Your payment provider. Stripe, PayPal, Mollie, Adyen, your acquiring bank — whoever settles your money. They have fraud teams who can watch for card-testing patterns and flag affected cards. If a card skimmer was injected into your checkout, this is how exposed cards get monitored before they're abused.
- Your host. Many compromises start at the hosting account, not the PrestaShop install, and your host can see things you can't (other sites on the same account, outbound spam, the cron that's mining crypto).
Where PrestaShop attackers actually hide
This is the part generic "you've been hacked" articles skip, and it's the whole game. Knowing the specific places PrestaShop infections live turns a hopeless "scan everything" into a targeted hunt. In rough order of how often we see each:
| Hiding spot | What to look for | Where |
|---|---|---|
| Web shells in writable dirs | PHP files with random names, or innocent-looking names (config.php, cache.php) where no PHP should be | img/, upload/, download/, var/cache/, theme upload folders |
| Rogue admin employee | An ps_employee row you didn't create — often with a plausible name and a recent date_add | ps_employee table / Advanced Parameters → Team |
| Card skimmer (Magecart) | JavaScript injected into the checkout that exfiltrates card fields to an external domain | Theme JS, ps_configuration, a malicious module, or DB-stored hooks |
| Override / module backdoor | A fake module folder or an override/ file that re-creates the attacker's access after you "clean" the site | modules/, override/classes/, override/controllers/ |
| Database-injected payload | Malicious code stored in CMS pages, configuration values, or module/theme settings (e.g. a custom-HTML or footer block), executed on render | ps_cms, ps_configuration, module settings tables |
A practical first sweep on the server: list every PHP file modified in the last 30 days and read each unfamiliar one. From your web root, find . -name "*.php" -mtime -30 -ls surfaces recently-touched files; cross-reference against a clean copy of the same PrestaShop version (download the exact release from the official site) so you can tell core files from tampered ones. Pay special attention to anything PHP living under img/ or upload/ — those directories should never contain executable PHP, and a single line in your .htaccess that denies PHP execution there is one of the cheapest hardening wins once you're clean.
Drop a tiny .htaccess into each upload directory (img/, upload/, download/) so even if a shell lands there again, the server refuses to run it. On Apache 2.4:
# img/.htaccess (and upload/, download/) — refuse to execute PHP
<FilesMatch "\.(php|php\d|phtml|phar)$">
Require all denied
</FilesMatch>
php_flag engine off
This is containment, not a fix: it stops a planted web shell from executing, but it does nothing about how the file got written in the first place — that's what the entry-point hunt below is for.
For the database side, dump the table and grep your ps_employee list against the people you actually employ, and search CMS/configuration content for <script, base64_decode, eval(, and external domains you don't recognise. If the breach turns out to be a checkout skimmer specifically, the mechanics of how it got in and how it siphons cards are worth understanding in detail — we dissected a real one in the anatomy of a Magecart-style attack on a PrestaShop store.
Lock the doors: rotating every credential the attacker may hold
Assume the attacker has a copy of everything they could read, and rotate it all. On PrestaShop, "all" is longer than people expect, and missing one item means they walk straight back in:
- Every back-office employee password — and delete any account you can't account for. Force a reset for the whole team, not just yourself.
- The database credentials in config/settings.inc.php (PS 1.6) or app/config/parameters.php (PS 1.7+). Change the MySQL user's password and update the file in the same move.
- The cookie keys — the _COOKIE_KEY_/_COOKIE_IV_ constants in settings.inc.php on PS 1.6, or the cookie_key/cookie_iv values (and new_cookie_key where present on PS 8/9) in parameters.php on PS 1.7+. If these leaked, old admin session cookies may still be valid. Rotating the keys alone isn't enough: after rotating, clear active server-side sessions and the cache, then force every employee to log out and reset their password — that's what actually kills the attacker's session.
- FTP/SFTP, SSH, and hosting-panel logins — a stolen FTP password is the most common way a "cleaned" site gets re-infected within hours.
- Any API keys / webhook secrets for payment and shipping integrations stored in module config.
Once credentials are rotated, this is the moment to close the door for good with two-factor authentication on the back office, so a leaked password alone is no longer enough — the how-to is in two-factor auth, password policies and admin security for PrestaShop. If your investigation showed the attack came in by hammering the login or via abusive IPs, layering in IP bans and reCAPTCHA on the login form mitigates automated login hammering. Don't treat it as a complete fix, though — reCAPTCHA can be bypassed and does nothing against credential stuffing with a valid stolen password, so pair it with 2FA, rate limiting and IP throttling, strong unique employee passwords, and log monitoring.
The 72-hour clock: your GDPR obligations
If your store has European customers — and if you ship to the EU or use a European payment processor, it does — the GDPR turns a technical incident into a legal one with a hard deadline. The rule that catches people out: you have 72 hours from becoming aware of the breach to notify your supervisory authority (the data protection authority in your country), unless the breach is unlikely to risk people's rights. A breach involving customer passwords, addresses, or payment data clears that bar easily, so plan to notify.
If the breach is likely to be high risk to the individuals — again, payment data and passwords qualify — you must also notify the affected customers directly, in plain language, telling them what happened, what data was involved, what you're doing, and what they should do (change their password, watch their statements, expect phishing that references the breach). This is exactly why the evidence snapshot from step one matters: you can't write an honest notification if you destroyed the data that tells you what was actually accessed. The 72-hour clock starts when you become aware, not when you finish investigating — so the notification often goes out while remediation is still in progress, with a follow-up once you know more. That's allowed and expected.
One practical note that's easy to miss: this clock runs in parallel with everything else in this guide. Containment, forensics, and the legal notification are happening at the same time, which is the main reason to keep a running, timestamped log of every action you take from the first hour. That log is both your forensic timeline and your proof of due diligence if a regulator asks.
Telling customers without making it worse
Customers forgive the store that told them first and despise the one they heard about from their bank or the news. The notification's job is to be honest and useful, not to minimise. State what happened in human terms, exactly which of their data was involved, and the specific actions they should take — and route the replies somewhere that won't drown your normal support. A dedicated breach-response address keeps panicked "was I affected?" emails out of your order-question queue.
Be ready for opportunists too: breach notifications are catnip for phishers who'll impersonate you to "help customers reset their password." Tell customers in the notification exactly which channel you'll use and that you'll never ask for their password — it costs one sentence and prevents a second wave of victims.
Don't restore the infection: rebuilding from a clean state
The most common recovery mistake is restoring last night's backup. If the attacker was in for two weeks, last night's backup contains the backdoor too — you'll restore the compromise and re-discover it next month. Work backwards from your snapshot to identify when the first malicious file or employee row appeared, then either restore from a backup that predates it or, more reliably, rebuild clean:
- Reinstall PrestaShop core from a fresh download of your exact version — replace the core files wholesale rather than trying to surgically clean them.
- Reinstall each module from its original source (the developer, not your possibly-tampered copy). Anything you can't source cleanly, drop.
- Re-apply only the override/ files and theme changes you can positively account for.
- Migrate data (orders, customers, products) from the database, but only after grepping it clean of injected payloads.
This is also the moment to fix your backup strategy so a clean rebuild is even possible next time: automated daily backups, stored off the production server, with enough retention (think 30+ days) that you can reach back past a slow-burn compromise. A backup that only goes back three days is useless against an attacker who sat quiet for a fortnight.
After the dust settles: close the vector for good
You found the entry point during forensics — now permanently close it, because re-compromise through the same hole is the single most common follow-up to a breach. The fix depends on what the investigation found:
- Outdated PrestaShop or a vulnerable module? Update. If you genuinely can't upgrade the core yet (a common reality on heavily-customised 1.6/1.7 stores), virtual patching lets you block the known exploit at the request layer without touching code — covered in advanced hardening for stores you can't upgrade yet.
- Weak or reused admin password? Password policy plus 2FA, per the admin security guide.
- Missing transport security or a leaky .htaccess? Get HTTPS right (SSL/HTTPS setup) and lock down the server rules (.htaccess security rules), including denying PHP execution in upload directories.
- Not sure where to even start hardening? The plain-English walkthrough for non-developers is securing your PrestaShop store, and the exhaustive version is the security hardening checklist.
Frequently asked questions
How do I know if my PrestaShop store has actually been hacked, or if it's just spam?
Look for the things a spammer can't fake: a ps_employee row you didn't create, PHP files modified in the last few days that you didn't touch (find . -name "*.php" -mtime -7), executable PHP under img/ or upload/, unexpected <script or base64_decode in your CMS pages or configuration, or your store redirecting to somewhere else for visitors but not for you. Junk carts and form spam are noisy but harmless; new admin accounts, injected scripts, and tampered core files are a compromise.
Should I take my store offline immediately?
Take the storefront offline to customers with maintenance mode, but keep the server running so you can investigate. Pulling the whole machine wipes volatile evidence (active sessions, attacker processes) before you've worked out how they got in — and without the entry point, you'll be re-infected within days. The one exception is a live card skimmer in checkout: there, stopping the bleed for customers comes first, and you call your payment provider in parallel.
Can't I just restore last night's backup and move on?
Usually no. If the attacker had been in for two weeks, last night's backup contains the backdoor too, so you'd restore the compromise and re-discover it next month. Work backwards from your evidence snapshot to find when the first malicious file or employee row appeared, then restore from a backup that predates it — or, more reliably, rebuild clean from a fresh core download and original module sources, migrating only data you've grepped clean.
Do I have to report the breach to anyone?
If your store has EU customers and the breach touched personal data (passwords, addresses, payment data), the GDPR gives you 72 hours from becoming aware to notify your supervisory authority, and you must notify affected customers directly if the risk to them is high. The clock starts when you become aware, not when you finish investigating, so the first notification often goes out while remediation is still running, with a follow-up later. That's expected.
How do I stop it happening again?
Close the exact vector your forensics found — patch the outdated core or module, kill the weak admin password, fix the leaky upload directory — because re-compromise through the same hole is the single most common follow-up to a breach. Then add the layers that make the next attempt harder: 2FA on the back office, off-server backups with 30+ days of retention, and the wider hardening checklist.
The genuinely hard part of post-breach recovery isn't the cleanup — it's knowing the moment you've truly closed every door, because a missed backdoor means you do all of this again. If you'd rather not carry that uncertainty alone, our team builds and audits PrestaShop stores for a living and works through exactly this kind of incident directly with store owners — no middleman, no reseller layer. So what does that get you? A second set of eyes that knows where PrestaShop infections hide, so you can reopen the storefront confident it's actually clean rather than hoping.
One last thing, and it's the one that matters most: write down what you did, in order, with timestamps, the moment the immediate fire is out. That record is your GDPR evidence, your insurance claim, and — when you read it back calmly next week — the most honest security audit you'll ever get of your own store. Most breaches trace back to a postponed update or a password everyone shared. Those aren't bad luck; they're the to-do list you now have no excuse to ignore.
Comments
No comments yet. Be the first!
Be the first to ask a question or share useful feedback.
Leave a comment
Share a question, an installation detail, or feedback that could help another reader.