Security · Magento 2

How to secure Magento 2: the essential hardening settings

Securing Magento 2 does not take a miracle extension. Most intrusions come in through well-known doors: an unpatched vulnerability, a guessed password, a file left open to anyone. Adobe says so itself. Here are the Magento 2 hardening settings, ranked by impact, each with why it matters and how to do it, followed by the false good ideas to avoid.

Illustration: the blue Tocsin24 bell rings above a shop with a padlocked door, protected by a blue shield, next to a phone showing an approved login code.

In short

  • Security patches first: no setting protects a store with a known vulnerability.
  • Then the admin panel: two-factor authentication, a custom admin address, one account per person with as few permissions as possible.
  • On the server: production mode, site served from pub/, read-only code, env.php protected.
  • Add the security headers (HSTS, X-Frame-Options, X-Content-Type-Options). And beware of settings copied without being understood.
Contents

Why harden Magento 2

Adobe has observed that most compromised stores are not breached by a brilliant attacker. Attackers mostly take advantage of known, unpatched vulnerabilities, weak passwords and wrong file permissions.

Hardening closes these doors, one by one. No single setting is enough on its own: what counts is adding them up. Here they are, from the most important to the finest.

1. Apply Magento security patches

Why. Adobe puts updates at the top of its recommendations: they are the main protection against attacks. A published vulnerability is soon known to everyone, attackers included.

How. Stay on a version that is still supported and apply the security patches every month. Everything is explained in our guide: Adobe security patches: check they are really applied. Also sign up for Adobe’s security notification service.

2. Secure the Magento 2 admin panel

The admin panel gives access to orders, customers and the code of your pages. It is target number one.

Keep two-factor authentication

Why. With two-factor authentication, a stolen password is no longer enough: the code from the phone is needed too. Adobe ranks it among its priority recommendations.

How. Since Magento 2.4.0, it has been on by default: each admin user sets it up on their first login. Adobe strongly advises against turning it off. The methods (Google Authenticator, Duo, Authy, U2F key) are chosen under Stores > Settings > Configuration > Security > 2FA. If nobody has ever asked you for a code when logging in, ask your developer.

Change the admin address

Why. Bots try common addresses such as /admin or /backend. A unique address reduces that exposure. Adobe points out that it will not stop a determined attacker: it is an extra layer, not a protection.

How. The safest way is to change it from the server (see further down). The admin panel lets you do it too (Stores > Settings > Configuration > Advanced > Admin > Admin Base URL, Use Custom Admin Path setting), but Adobe advises against it if you do not know how to fix a configuration file on the server: a mistake cuts off access, and only the server can then restore it. Check with your hosting provider too: some firewalls expect the standard address. If you can, restrict access to the admin panel to certain IP addresses or to a VPN, as Adobe recommends.

Set up account security

Under Stores > Settings > Configuration > Advanced > Admin > Security:

  • Add Secret Key to URLs: leave it on Yes. This is the default; it adds a secret key to admin addresses.
  • Admin Account Sharing: No, so that one account cannot be used on several devices at the same time.
  • Maximum Login Failures to Lockout Account: six attempts by default. Do not leave the field empty: empty means unlimited attempts.
  • Admin Session Lifetime: how long an idle session lasts, 900 seconds (15 minutes) by default.
  • Password Lifetime: how long passwords last. Adobe cites the PCI DSS standard, which requires them to be changed at least every 90 days.

Add reCAPTCHA to the admin login page, against automated password guessing. And follow the principle of least privilege: one account per person, with a role limited to what they need. To review the accounts: spotting a suspicious admin account.

3. Switch Magento to production mode

Why. In developer mode, Magento shows errors in the browser, with file paths and details of the code. In production mode, errors are written to the logs and never shown to visitors. Production mode is also faster.

How. An online store must be in production mode. The command is further down.

4. Serve only Magento’s pub/ folder

Why. Magento contains files that must never be readable from a browser: app/etc/env.php (database access, encryption key), the logs in var/log, the .git folder, composer.json. Adobe explains that if the site is served from the Magento root folder, the rest of the files can be reached from a browser.

How. The website root must be the pub/ folder. That is already the case with the nginx.conf.sample file shipped with Magento. Adobe also asks you to tidy up: no log file, .git folder, database backup or phpinfo file should be reachable.

5. Make the Magento code read-only

Why. An attacker who can write to the code can hide a backdoor or a card skimmer in it. In production, Adobe asks you to remove write access to the code and configuration, and to make app/etc/env.php unreadable for other users on the server.

How. Adobe recommends two users on a dedicated server: one for the web server, another for commands and cron, which owns the files. The commands are further down. For an update, the files are made writable, then set back to read-only.

6. Protect Magento’s encryption key and database

The encryption key protects the passwords and sensitive data stored by Magento. Adobe advises changing it regularly, and as soon as it may have leaked: after an intrusion, or if env.php has been exposed. Since Magento 2.4.8, this can only be done from the command line. The change logs out all customers and admin users.

The database: Magento connects to it with the user given at installation, root by default. Adobe’s procedure creates a dedicated user with permissions on the Magento database only. Do not let the store connect with an account that controls the whole database server.

Sensitive settings: Adobe recommends locking critical configuration values with bin/magento config:set --lock-env. The value is written to app/etc/env.php and can no longer be changed from the admin panel.

7. Add HTTP security headers to Magento

These are instructions the server sends to the browser with every page.

Header What it does In Magento
Strict-Transport-Security (HSTS) The browser only uses HTTPS for your site from then on. Enable HTTP Strict Transport Security (HSTS) setting under Stores > Settings > Configuration > General > Web > Base URLs (Secure), or on the web server.
X-Frame-Options Stops your pages from being displayed inside another site’s frame (clickjacking). Sent by Magento, SAMEORIGIN by default, set in app/etc/env.php.
X-Content-Type-Options: nosniff The browser does not guess a file’s type: a text file cannot turn into a script. To be added on the web server.
Content-Security-Policy Lists the allowed sources of scripts. Since Magento 2.4.7, in restrictive mode on the payment pages, in “report-only” mode elsewhere.

OWASP also recommends removing headers that reveal software versions, such as X-Powered-By.

8. Keep Magento extensions few and safe

Why. Every extension adds code, so possible vulnerabilities, and one more vendor to keep track of. Adobe recommends limiting the number of extensions and vendors.

How. Get your extensions from the Adobe Commerce Marketplace or through your developer. Uninstall the ones you no longer use: a disabled extension stays in the code. Have the extensions’ code reviewed when possible, and follow their updates as you do Magento’s.

What not to do when securing Magento

  • Piling up “security” extensions. One more extension means more code and one more vendor. It replaces neither the patches nor the settings above.
  • Believing a hidden admin address is enough. Adobe says so: it reduces bot noise, not the risk from a determined attacker.
  • Turning off two-factor authentication because it is a nuisance. Adobe strongly advises against it.
  • Making everything writable to get rid of a permissions error. In production, the code must stay read-only.
  • Copying a configuration found online without understanding it. An HSTS duration that is too long, a badly changed admin address or a modified minimum password length (Adobe reports compatibility issues) can lock you out of the store or the admin panel.
  • Leaving an old account active: a former employee, a former agency, a test account.

You manage the server: harden Magento 2 on Debian or Ubuntu

The bin/magento commands are run from the Magento folder, here /var/www/store, as the user who owns the files.

  1. Check the mode, then switch to production if needed. The first command shows the current mode (default, developer or production). Switching to production compiles the code and deploys the static files: do it outside trading hours.

    Terminal, from the Magento folder
    Current mode bin/magento deploy:mode:show Switch to production bin/magento deploy:mode:set production
  2. Read and change the admin address. Choose a unique word, without admin or backend, made only of letters, digits and the _ character. Replace my_unique_address with yours.

    Terminal, from the Magento folder
    Current address bin/magento info:adminuri New address bin/magento setup:config:set --backend-frontname="my_unique_address"
  3. Check that the two-factor authentication module is enabled.

    Terminal, from the Magento folder
    bin/magento module:status Magento_TwoFactorAuth

    The expected answer is Magento_TwoFactorAuth : Module is enabled.

  4. Make the code read-only. Here is Adobe’s command for a two-user setup, in production mode, to be run as root. It removes write access for the web server group on the code and configuration, and removes all access to env.php for other users.

    Terminal, from the Magento folder, as root
    find app/code lib pub/static app/etc generated/code generated/metadata var/view_preprocessed \( -type d -or -type f \) -exec chmod g-w {} + && chmod o-rwx app/etc/env.php stat -c '%A %U:%G %n' app/etc/env.php

    The second command checks the result: env.php must have no permissions for “others”, for example -rw-r-----. For an update, Adobe gives the reverse command on the same page.

  5. Serve pub/ and check for exposed files. With Nginx, include Magento’s nginx.conf.sample file: it sets the root to pub/ and denies sensitive files. Then, from any computer, check how the site responds for a few paths (replace the address with your store’s):

    Terminal, from any computer
    for p in /.git/HEAD /app/etc/env.php /setup/ /var/log/system.log; do printf '%s ' "$p"; curl -s -o /dev/null -w '%{http_code}\n' "https://www.example.com$p"; done

    A 404 or 403 code is normal. A 200 code means you need to open the address and see what is being served.

  6. Check the security headers.

    Terminal, from any computer
    curl -sI https://www.example.com/ | grep -i -E '^(strict-transport-security|x-frame-options|x-content-type-options|content-security-policy)'

    Each header present is shown on its own line. An empty answer means none is sent. With Nginx, add for example add_header X-Content-Type-Options "nosniff" always; in the site block, then run nginx -t before reloading.

  7. Change the encryption key if it may have leaked. Follow Adobe’s procedure: maintenance mode, cron stopped, backup of env.php, then:

    Terminal, from the Magento folder
    bin/magento encryption:key:change

    All customers and admin users will have to log in again.

  8. Look for known vulnerabilities in extensions and libraries.

    Terminal, from the Magento folder
    composer audit --locked

    The command lists the security advisories published on Packagist for the installed packages. It does not see extensions installed outside Composer, in app/code.

Tocsin24 checks what can be seen from the outside, every day

Every day, and on demand, Tocsin24 probes your store the way a visitor would, one request per check, never attempting an attack. It checks that none of these are served: the .git folder, .env, app/etc/env.php, app/etc/config.php, composer.json, composer.lock, auth.json, the logs in var/log, the setup/ wizard, a phpinfo.php or .DS_Store file. A file is only reported if its content is actually recognised, not on a mere 200 code: an exposed file opens a critical incident, which closes on its own once the file no longer responds. Tocsin24 also recommends turning off directory listing and closing GraphQL if your store does not use it, and checks that code integrity is being monitored. A protection that was in place and then disappears is reported to you.

For each point, the Hardening page tells you what was seen, why it is a risk, how to fix it and the command to check. The free quick audit checks HTTPS and the HSTS, X-Frame-Options and X-Content-Type-Options headers. But continuous monitoring does not read your settings: not two-factor authentication, the admin address, the Magento mode, file permissions or security headers. Those points remain for you or your developer to check.

Durcissement

Ce que le serveur web ne devrait pas servir, et les protections à mettre en place : vérifié chaque jour par une sonde, depuis l'extérieur.

Vérifier maintenant

Fichiers et chemins exposés 1 à faire

  • À faire composer.json non servi incident

    Observé : /composer.json répond 200 avec le contenu attendu d'un tel fichier : il est lisible par quiconque. (le 23 octobre 2026 à 05:20)

    Pourquoi : composer.json révèle les paquets et versions exacts installés : les failles à tenter se lisent dedans.

    Correction : Racine du site sur pub/ (Magento) ; sinon refuser « \.json$ » à la racine ou déplacer le projet hors du dossier servi.

    curl -s -o /dev/null -w '%{http_code}\n' 'https://www.example.com/composer.json'

Application screens with example values.

Frequently asked questions

How do I secure a Magento 2 store?

In this order: apply Adobe's security patches, keep two-factor authentication, change the admin address, limit account permissions, switch to production mode, serve only the pub/ folder, make the code read-only and add the security headers.

How do I change the Magento 2 admin URL?

On the server, run bin/magento setup:config:set --backend-frontname="your_address" from the Magento folder. bin/magento info:adminuri shows the current address. Pick a unique word, neither admin nor backend. Adobe advises against changing it from the admin panel unless you know how to fix the configuration on the server.

Can I turn off two-factor authentication in Magento?

Technically yes, but Adobe strongly advises against it. It has been on by default since Magento 2.4.0 and is one of Adobe's priority recommendations.

How do I know whether Magento is in production mode?

On the server, bin/magento deploy:mode:show shows the current mode. In production mode, errors are never shown to visitors.

Is a security extension enough to protect Magento?

No. Intrusions mostly come through unpatched vulnerabilities, weak passwords and wrong permissions. An extension adds more code to keep an eye on. It replaces neither the patches nor the basic settings.

Portrait of Cédric Michel

Cédric Michel

Cédric has been building Magento stores for 18 years and holds the Adobe Commerce Developer Expert certification. He created Tocsin24 to monitor the security and health of Magento 2 stores and WordPress sites.

Adobe Commerce Developer Expert badge Adobe Commerce Developer Expert
Verify the certification on Adobe’s website

Sources

  1. Adobe: Secure your Commerce site and infrastructure (security best practices)
  2. Adobe: two-factor authentication
  3. Adobe: Magento Open Source 2.4.0 release notes
  4. Adobe: use a custom admin URL
  5. Adobe: display or change the admin URI
  6. Adobe: `setup:config:set` options
  7. Adobe: admin security
  8. Adobe: application modes
  9. Adobe: set the mode
  10. Adobe: serving the pub/ folder (docroot)
  11. Adobe: file system permissions in development and production
  12. Adobe: encryption key
  13. Adobe: set configuration values (`config:set --lock-env`)
  14. Adobe: prevent clickjacking (X-Frame-Options)
  15. Adobe: Content Security Policy
  16. OWASP: HTTP Security Response Headers Cheat Sheet
  17. MDN: Strict-Transport-Security
  18. Magento source code: `nginx.conf.sample`
  19. Composer: the `audit` command