How to Perform a Magento 2 Security Audit: A Step-by-Step Checklist for Store Owners

Hey — if you manage a Magento 2 store yourself (or collaborate closely with the tech person who does), this post vous donne a practical, étape-by-étape checklist for running a sécurité audit. Think of it as a friendly walkthrough you can use to verify that the server, Magento instance, and extensions aren’t leaving obvious holes. I’ll keep the tone relaxed and show real commands and code snippets so you can try things as you go.

This checklist covers the technical essentials: server configuration and hardening, fichier permissions, updates, auditing tiers extensions, defending against common attacks (XSS, SQLi, CSRF), real-time monitoring and intrusion detection, and finally a concrete post-audit plan for maintenance. Si vous prefer, follow the sections in commande or pick the parts that worry you most.

Quick map: what you’ll do in this audit

  • Prepare: backups, maintenance mode, and access controls
  • Server configuration avis (TLS, firewall, PHP, MySQL)
  • File ownership & permissions check
  • Magento updates, correctifs and dependency checks
  • Third-party extension audit and vulnérabilité evaluation
  • Protection against XSS, SQL injection, CSRF
  • Set up monitoring and intrusion detection (fail2ban, Wazuh/OSSEC)
  • Post-audit plan: runbook, scheduled maintenance, and preventive tasks

Avant you start: preparation

Run this audit during a low-traffic window. Always take a full backup and, ideally, work on a staging clone if you’ll apply changes. At minimum, put the store into maintenance mode before making risky changes.

# Put Magento in maintenance mode
bin/magento maintenance:enable

# Take a quick DB dump and archive the pub, app, and vendor directories
mysqldump -u magento_user -p magento_db > /backup/magento_db_$(date +%F).sql
tar -czf /backup/magento_files_$(date +%F).tar.gz app pub vendor

Assurez-vous you have emergency access to the server (SSH clé) and that another admin account exists if your primary login gets locked out.

1) Server configuration checklist

C'est the foundation. If the OS, web server, or PHP is misconfigured, Magento won’t be secure even if the application is tidy.

1.1 Verify TLS/SSL

Run an SSL check (you can use openssl locally) and make sure you only support modern TLS versions and strong ciphers.

# Quick TLS check (basic)
echo | openssl s_client -connect your-site.com:443 -tls1_2

# Check supported protocols (more thorough scanners exist externally)

Require HTTPS site-wide, set HSTS, and ensure certificates are valid and auto-renewed (use Let’s Encrypt or your CA’s automation).

1.2 Web server hardening (Nginx / Apache)

Ensure that débogage pages are disabled, répertoire listings are off, and that the server returns minimal information in erreur pages.

# Example Nginx hardening snippets (add to server block)
server_tokens off;
client_max_body_size 20M;

# Disable .git and .env access
location ~ /(\.|composer\.|git) {
  deny all;
}

# Recommended security headers
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header Referrer-Policy no-referrer-when-downgrade;
add_header X-XSS-Protection "1; mode=block";

For Apache, ensure ServerSignature Off and ServerTokens Prod are set.

1.3 Firewall and network

Limit SSH access (allow only admin IPs or use a VPN), block unused ports, and enable a host firewall (ufw, nftables, or iptables). Si vous run a web application firewall (WAF), ensure the rules are active.

# Example UFW commands
ufw allow OpenSSH
ufw allow 80,443/tcp
ufw enable

# Limit SSH to a specific IP (replace x.x.x.x)
ufw allow from x.x.x.x to any port 22

1.4 PHP configuration

Check PHP options: disable dangerous fonctions, set proper memory and execution limits, and ensure display_erreurs is off in production.

# php.ini suggestions (production)
display_errors = Off
log_errors = On
memory_limit = 2G
expose_php = Off

# disable dangerous functions
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec

Also, set proper PHP-FPM process owner matching the web server’s utilisateur and separate pools for different sites if hosting mulconseille stores.

1.5 Database (MySQL / MariaDB)

Ensure remote DB access est désactivé or limited to known hosts. Use strong DB utilisateur passwords and remove root remote logins.

# Check current user grants inside MySQL
SELECT user, host FROM mysql.user;

# Example: create a dedicated Magento DB user with limited privileges
CREATE USER 'magentouser'@'localhost' IDENTIFIED BY 'strongpassword';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON magento_db.* TO 'magentouser'@'localhost';
FLUSH PRIVILEGES;

Enable MySQL’s slow query log and audit queries that look suspicious. Use database backups and test restores periodically.

2) File ownership and permissions

Many compromises occur because fichiers are writable by the wrong utilisateur. Magento’s recommended approche is to make sure the web server utilisateur owns generated and var répertoires while keeping most fichiers read-only.

# Typical ownership and permissions (adjust  and )
sudo chown -R : .
sudo find . -type f -exec chmod 644 {} \;   # 644 for files
sudo find . -type d -exec chmod 755 {} \;   # 755 for directories

# Writable dirs for Magento 2
sudo chown -R : var pub/generated pub/static app/etc
sudo chmod -R g+ws var pub generated

# OR a recommended set from Magento docs (safe default)
find var vendor pub/static pub/media app/etc -type f -exec chmod u+w,g+w {} \;
find var vendor pub/static pub/media app/etc -type d -exec chmod u+w,g+w {} \;

Why this matters: if an attacker can write to app/code or app/etc, they can modify config or drop backdoors. Keep write permissions minimal and use déploiement pipelines to update code rather than editing in-place.

3) Updates & correctifs

Magento core correctifs (including correctif de sécuritées) and PHP/library updates are crucial. Never postpone sécurité updates indefinitely.

3.1 Check Magento version and correctifs

# Magento CLI shows version
bin/magento --version

# Composer shows installed Magento packages
composer show | grep magento

# Quick check for open security updates via Composer Audit (if using Composer v2)
composer audit

If composer audit returns vulnérabilités, avis the advisory and mise à jour the affected package. Test mise à jours on staging first.

3.2 Keep tiers libs updated

Composer manages dependencies. Use a staging environment to run composer update and test before production déploiement.

# Example upgrade workflow (on dev/staging)
composer update vendor/package --with-dependencies
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy

4) Audit tiers extensions and evaluate vulnérabilités

Third-party modules are a major source of vulnérabilités. Your job is to inventaire, validate, and if necessary isolate or correctif modules.

4.1 Inventory installed modules

# List modules via Magento CLI
bin/magento module:status

# Also check composer.json and composer.lock
cat composer.json | jq .require
cat composer.lock | jq '.packages[] | {name,version}'

Export a list of modules and their versions for later tracking.

4.2 Check sources and support

For each tiers module, ask:

  • Is it from a reputable vendor?
  • Is it actively maintained?
  • Is there sécurité information or rapported CVEs for it?
If a module hasn’t been updated in >1 year and manages sensitive fonctionality (paiement, payment, zone d'administration), treat it with suspicion.

4.3 Automated vulnérabilité checks

Use tools tel que:

  • composer audit
  • Security scanners like OWASP ZAP for application-level test
  • Static analysis tools to recherche for dangerous patterns

Example: use grep or ag to find direct SQL calls or eval() usage in modules:

# Search for risky PHP functions in app/code and vendor
grep -R "eval\(|base64_decode|exec\(|shell_exec|passthru|system\(" app/code vendor || true

If a module contains obfuscated code (base64 or eval) and you don’t expect it, isolate and replace it immediately.

4.4 Disable or sandbox risky modules

When in doubt, disable non-essential modules until you can validate them:

# Disable a module
bin/magento module:disable Vendor_Module
bin/magento cache:flush

And keep an emergency plan: if a module doit être removed, test removal on staging and then remove via composer to keep composer.lock consistent.

5) Protection against common attacks

I’ll cover practical checks and code exemples for XSS, SQL injection, and CSRF — the most common vectors you’ll face.

5.1 Cross-Site Scripting (XSS)

Magento provides helpers to escape output. Si vous or a tiers module echoes raw utilisateur input into a PHTML template, it’s a red flag.

# BAD (vulnerable)
<?php echo $block->getData('user_comment'); ?>

# GOOD (escaped)
<?php echo $block->escapeHtml($block->getData('user_comment')); ?>

# For attributes
<?php echo $block->escapeHtmlAttr($someValue); ?>

Audit templates for direct echo usage and enforce escaping fonctions: escapeHtml, escapeHtmlAttr, escapeUrl, etc.

5.2 SQL Injection

Magento’s framework uses the DB adapter which supports paramètreized queries. Avoid building queries by concatenation with utilisateur input.

# BAD (string concat, vulnerable)
$sql = "SELECT * FROM custom_table WHERE id = " . $inputId;
$result = $connection->fetchAll($sql);

# GOOD (parameterized)
$sql = "SELECT * FROM custom_table WHERE id = ?";
$result = $connection->fetchAll($sql, [$inputId]);

# Or using quoteInto
$sql = $connection->quoteInto("SELECT * FROM custom_table WHERE id = ?", $inputId);
$result = $connection->fetchAll($sql);

Scan custom modules for concatenated SQL and replace them with paramètreized méthodes.

5.3 Cross-Site Request Forgery (CSRF)

Magento uses form clés to protect forms. Ensure that custom forms include the form clé and that AJAX posts include it too.

# Include form key in templates
<input name="form_key" type="hidden" value="<?php echo $block->escapeHtml($block->getFormKey()); ?>" />

# For AJAX (JS) include form_key in POST
var formKey = window.FORM_KEY;
fetch('/your/endpoint', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ form_key: formKey, data: myData })
});

On the server side, ensure contrôleurs extend the right class so Magento checks the form clé automatically when needed, or manually validate $this->_formKeyValidator->validate($this->getRequest()).

6) Real-time monitoring and intrusion detection

Auditing once is not enough. You need ongoing monitoring for suspicious activity and a way to rapidly triage alerts.

6.1 Log centralization

Aggregate logs from web server, PHP-FPM, and Magento (system and exception logs). Ship them to a central logging platform (Elastic Stack, Splunk, or hosted alternatives).

# Example: tail Magento logs
tail -n 200 var/log/system.log
tail -n 200 var/log/exception.log

Look for repeated login failures, sudden spikes in exceptions, or unusual admin activity.

6.2 Fail2ban for brute force prevention

Protect SSH and Magento admin login endpoints by blocking repeated failed attempts. Create a jail for admin login or use the built-in auth logs if you proxy requests.

# Example jail.local snippet for SSH
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5

# Example for Nginx auth failure (custom filter required)

6.3 IDS/Endpoint detection (Wazuh/OSSEC)

Install an IDS like Wazuh or OSSEC to detect rootkits, fichier integrity changes, and suspicious behavior. Configure alerts for changes to app/etc/env.php, cronjobs, and new PHP fichiers in pub/.

6.4 File integrity monitoring

Calculate and monitor checksums of your codebase. If a fichier changes unexpectedly in production, trigger an alert and isolate the instance.

# Simple checksum using sha256
find . -type f -exec sha256sum {} \; | sort -k2 > checksums_$(date +%F).txt
# Compare to known-good manifest
sha256sum -c manifest.sha256

7) Audit of admin utilisateurs and access controls

Check admin accounts and roles. Remove unused admin utilisateurs and ensure multifactor authentication (MFA) est activé for all admin logins.

# List admin users in DB
SELECT user_id, username, email, created, modified FROM admin_user;

# Disable an admin user in the DB (emergency)
UPDATE admin_user SET is_active=0 WHERE username='dangerous_user';

Prefer enabling Two-Factor Authentication (2FA) for admin utilisateurs. Magento has a built-in 2FA module; ensure it’s enabled and enforced for admin roles.

8) Check tâches cron and background tasks

Malicious cron entries let attackers persist. Review crontab entries for the Magento utilisateur and system crontabs.

# List crons for the magento user
crontab -u magento_user -l

# Example Magento cron entries to expect
* * * * * /usr/bin/php /path/to/bin/magento cron:run | grep -v "Ran jobs by schedule" > /dev/null

Si vous find odd or unfamiliar tâches cron, move the server to maintenance and investigate.

9) Scan for application-level vulnérabilités

Automated scanners can find common web vulnérabilités. Run OWASP ZAP or similaire àols against staging first.

  • Scan login and form endpoints for XSS and CSRF weaknesses.
  • Test shopping flow for injection points.
  • Run authenticated scans for panneau d'administrations to see privilege escalation paths.

Keep in mind: automated tools can return false positives. Review findings manually.

10) Post-audit action plan & preventive maintenance

Après the audit, put together a short runbook that includes:

  • Immediate correctifes applied and who applied them
  • Backups taken and their locations
  • Items requiring staged test or vendor support
  • A schedule for follow-up checks

10.1 Example runbook template

Runbook: Magento 2 Security Audit - 2025-XX-XX
- Executor: Alice (Ops)
- Backup: /backup/magento_db_2025-XX-XX.sql (verified)
- Issues found:
  1) Outdated third-party payment module Vendor_Pay (v1.2.0) -> disabled / scheduled replacement
  2) File perms: app/etc writable by web group -> corrected
  3) Missing HSTS -> enabled in nginx.conf
- Follow-ups:
  - Schedule composer update on staging: 2025-XX-XX
  - Enable WAF ruleset: 2025-XX-XX

10.2 Maintenance schedule (suggested)

  • Weekly: avis logs for spikes and repeated failures
  • Monthly: run composer audit, check for Magento correctif de sécuritées
  • Quarterly: full vulnérabilité scan and penetration test on staging
  • Annually: avis access controls and update internal documentation

10.3 Emergency playbook

Have a short emergency playbook for when you suspect compromise. It should include étapes to:

  1. Isolate the server (remove from load balancer)
  2. Take forensic copies of disk and DB
  3. Rotate application secrets and admin passwords
  4. Restore from last known-good backup and correctif the vector

11) Example: end-to-end mini audit you can run in 45 minutes

Here’s a condensed checklist you can run quickly to get a baseline. It’s not exhaustive but will highlight major problèmes.

  1. Backup and enable maintenance mode (3 minutes)
  2. Check Magento and PHP versions (2 minutes): bin/magento --version; php -v
  3. Verify composer audit (5 minutes): composer audit
  4. Check fichier ownership & permissions (5 minutes): run the find commands from above
  5. Check admin utilisateurs (5 minutes): query admin_utilisateur table
  6. Review web server TLS and headers (10 minutes): check openssl and Nginx config
  7. Scan for obvious XSS/SQL patterns in code (10 minutes): run grep commands

Document what you find and schedule a follow-up for anything that needs a careful correctif.

12) Practical conseils and common pitfalls

  • Don’t edit code in production. Use CI/CD so that changes are auditable.
  • Use environment-specific credentials, not the same clés across environments.
  • Disable développeur mode and verbose erreur messages in production.
  • Keep a minimal list of admin utilisateurs and enforce strong passwords + 2FA.
  • Monitor fichier-size changes: sudden gligneth in a PHP fichier often indicates a web shell.

13) Useful commands résumé

# Magento version
bin/magento --version

# List enabled modules
bin/magento module:status

# Composer audit
composer audit

# Backup DB
mysqldump -u user -p dbname > /backup/db.sql

# Check permissions
find . -type f -exec chmod 644 {} \;
find . -type d -exec chmod 755 {} \;

# Scan for risky code
grep -R "eval\(|base64_decode|shell_exec|passthru|system\(" app/code vendor || true

# Tail Magento logs
tail -f var/log/system.log var/log/exception.log

Wrap up

Security is ongoing. This audit checklist vous donne a structured way to assess and harden a Magento 2 store. Si vous run through the étapes above, you’ll catch most common misconfigurations and risky tiers code. For Magefine clients specifically: pair this audit habit with a reliable hosting environment that provides regular backups, correctifing assistance, and a hardened stack optimized for Magento. That combo buys you time to focus on running the store while keeping risk low.

Si vous want, I can generate a tight printable checklist (one-page PDF style) basé sur the items above or create a templated runbook you can clone and reuse for subsequent audits. Tell me which format you prefer.