← Back to blog

Magento 2 Admin Security Hardening Checklist

Rodrigo Biazzi

The Magento admin can create users, change payment settings, edit CMS content shown on every page and export customer data. Whoever controls it controls the store. Most of the hardening is configuration and process, not code, and it can be done in an afternoon.

This is the checklist I use on Magento Open Source and Adobe Commerce 2.4 stores. The items are ordered roughly by how much risk they remove for the effort.

1. Keep two factor authentication on

Since 2.4.0, the Magento_TwoFactorAuth module is enabled by default and every admin user must set up a second factor. Developers often disable it locally and the change sometimes leaks to production through config.php. Check it:

bin/magento module:status Magento_TwoFactorAuth

It must be enabled in production. A stolen admin password is the most common way into the admin, and 2FA is what stops it. The setup, providers and recovery steps are covered in the two factor authentication guide.

2. Change the admin path

A custom admin path does not make the admin secure, but it removes the store from the large amount of automated traffic that tries /admin with common passwords. Set it in app/etc/env.php through the CLI:

bin/magento setup:config:set --backend-frontname="manage_k7q2"
bin/magento info:adminuri

Pick something that is not a dictionary word and not the store name. Do not put it in public places like robots.txt, which some stores still do by mistake.

3. Restrict the admin by IP

If the people who use the admin work from known addresses or through a VPN, restrict the admin path at the web server. This is the single most effective control on this list, because an attacker with a valid password still cannot reach the login form. With Nginx, add a location before the PHP location block of the Magento sample config:

location ~ ^/(index\.php/)?manage_k7q2 {
    allow 203.0.113.10;
    allow 198.51.100.0/24;
    deny all;
    try_files $uri $uri/ /index.php$is_args$args;
}

If the store runs behind Cloudflare, Fastly or a load balancer, Nginx sees the proxy address, not the client. Configure the real IP module with the trusted proxy ranges first, or apply the restriction at the CDN instead. Test from an address that is not allowed and confirm you get a 403.

When fixed addresses are not practical, a VPN or an access proxy in front of the admin path gives the same result.

4. Tune lockout, session and password settings

These live under Stores, Configuration, Advanced, Admin, Security. You can also set them from the CLI, which is easier to repeat across environments:

bin/magento config:set admin/security/session_lifetime 3600
bin/magento config:set admin/security/lockout_failures 5
bin/magento config:set admin/security/lockout_threshold 30
bin/magento config:set admin/security/password_lifetime 90
bin/magento config:set admin/security/password_is_forced 1
bin/magento config:set admin/security/admin_account_sharing 0
bin/magento config:set admin/captcha/enable 1
  • session_lifetime is in seconds. One hour is a reasonable value for most teams.
  • lockout_failures and lockout_threshold lock the account after a number of failed logins, for a number of minutes. Unlock a user with bin/magento admin:user:unlock.
  • admin_account_sharing set to 0 prevents the same account from being logged in from two places at once. It also discourages shared logins, which is the real goal.
  • Keep admin/security/use_form_key enabled. Turning off the secret key in URLs is sometimes suggested for convenience, and it weakens CSRF protection.

To keep these values from being changed in the admin, lock them in app/etc/env.php with config:set --lock-env. Locked values show as read only in the admin.

5. Clean up users and roles

Every store accumulates admin users: former employees, agencies that finished their project, a support account created for a vendor years ago. List them:

SELECT user_id, username, email, is_active, logdate
FROM admin_user
ORDER BY logdate;

Disable or delete accounts that have not logged in for months and accounts of people who no longer work on the store. One person, one account, with a personal email address. Shared accounts make it impossible to know who did what.

Then review roles under System, Permissions, User Roles. Most people do not need full access. Customer service needs orders and customers, not system configuration or integrations. Content editors need CMS, not payment settings. Give the Administrators role only to the few people who really need it.

6. Review integrations and API access

API access is admin access through another door. Under System, Extensions, Integrations, check each integration: who created it, what resources it has, whether it is still used. Remove the ones nobody can explain. Integrations should have only the resources they need. An ERP that syncs orders does not need access to CMS or admin users.

Also review admin tokens. Admin bearer tokens are created with the admin credentials of a user, so a script that logs in as a real admin user inherits all that user's permissions. Prefer integrations with limited resources for automated access. The details are in the web API authentication guide.

7. Watch configuration that renders HTML

Several admin fields output raw HTML on the storefront: the miscellaneous scripts in the HTML head design setting, the footer, CMS blocks and widgets. An attacker with admin access, or with a SQL injection, often uses these to inject a payment skimmer, because no file changes. Review them regularly and alert on changes. A simple check:

SELECT config_id, scope, scope_id, path, updated_at
FROM core_config_data
WHERE path LIKE 'design/%'
ORDER BY updated_at DESC;

Adobe Commerce includes Admin Actions Log, which records who changed what in the admin. On Magento Open Source there is no built in equivalent, so if you need an audit trail, use an extension from a trusted vendor or log configuration changes yourself.

8. Protect the server side too

  • Use HTTPS for the whole site, including the admin.
  • Keep app/etc/env.php readable only by the PHP user. It holds the encryption key and database password.
  • Do not expose phpMyAdmin, Adminer or similar tools on a public URL.
  • Do not leave the store in developer mode in production. It shows stack traces with paths and sometimes data.
  • Apply security patches on time. Several past Magento vulnerabilities gave admin level access without any password. See how to stay up to date with security patches.

A short recurring review

Hardening is not a one time task. Once a quarter, list admin users and integrations, check roles, review HTML configuration fields and confirm 2FA and the IP restriction are still in place. It takes less than an hour and catches the slow drift that weakens most admin setups.

FAQ

Is changing the Magento admin URL enough to protect it?

No. It reduces automated login attempts, but anyone who finds the path can still try. Combine it with 2FA and an IP or VPN restriction.

How do I unlock a locked Magento admin user?

Run bin/magento admin:user:unlock followed by the username. The lockout comes from the failed login settings under Advanced, Admin, Security.

Does Magento Open Source log admin actions?

Not in detail. The Admin Actions Log is an Adobe Commerce feature. On Open Source you need an extension or your own logging for an audit trail.

Should API scripts use an admin user login?

It is better to create an integration with only the resources the script needs. An admin token carries all the permissions of that admin user.

I am available for freelance Magento and Adobe Commerce work, including security reviews. If you need help with this, get in touch.

Related articles