How to Improve WordPress Security by Restricting Plugin Installs

Do you need a learn WordPress? Learn by doing now!

Sharing is caring!

Subscribe to our newsletter

Restricting plugin installs in WordPress is very inconvenient. You lose one click installs and fast updates in wp-admin. You may need File Manager, FTP, staging, or WP-CLI but it's a strong security measure to have on the live site. 

That way you control when the updates will happen.

Many successful WordPress compromises happen after an attacker gets admin access from a compromised plugin or theme. From there, a common next step is to inject a malware either as custom code or by installing an infected version of a plugin or a theme. 

If you restrict installs and updates in wp-admin, you remove that quick path.

This post explains how plugin installs work, which wp-config.php constants control them, and how to use a simple workflow so you get the security benefit without making maintenance painful.

Why restricting installs improves security? If an attacker gets an admin login, they can often:

  • Install a plugin that runs hidden code
  • Install a theme that contains a backdoor
  • Replace files through updates
  • Create additional admin users for later access

Restricting file modifications does not make your site super secure. It reduces the impact of one of the most common escalation steps inside WordPress admin area.

How to installs a WordPress plugin. There are several common ways. All of them end up with WordPress writing files into wp-content/plugins.

Path 1: Install from WordPress.org inside wp-admin

  1. You go to Plugins, Add New.
  2. WordPress searches the official WordPress.org plugin directory.
  3. You click Install Now.
  4. WordPress downloads the plugin zip from WordPress.org.
  5. WordPress extracts the zip on your server.
  6. WordPress writes the files into wp-content/plugins.
  7. You click Activate.

Path 2: Upload a specific version (manual zip upload) or via FTP.
This is useful when you need a specific plugin version, or the plugin is not in the directory.

  1. You download the plugin zip file to your computer.
    If it is hosted on WordPress.org, you can download a specific version from the plugin’s Advanced View page.
  2. In wp-admin you go to Plugins, Add New, then Upload Plugin.
  3. You choose the zip file and click Install Now.
  4. WordPress extracts the zip and writes files into wp-content/plugins.
  5. You click Activate.

Path 3: Install and manage plugins with WP-CLI
This is for developers and advanced site owners who use the command line.
WP-CLI can install, activate, deactivate, update, and delete plugins.

Examples
install a plugin:
wp plugin install seo-framework --activate

Install a specific version:
wp plugin install seo-framework --version=5.1.2 --activate

Update all plugins:
wp plugin update --all

Security note
WP-CLI still writes files to wp-content/plugins. If you allow WP-CLI access on the server, you must secure server logins. Restricting installs in wp-admin helps, but it does not control what trusted server users can do. They are suppose to be trusted but sometimes they can have the passwords stolen so it's good to think about that too.

The wp-config.php constants that matter
These settings are simple. The impact is big.

DISALLOW_FILE_EDIT disables the built-in code editor


What it does
Disables the plugin and theme editor in wp-admin.

Why it matters for security
If an attacker gets admin access, they cannot paste a backdoor into a theme file using the editor.

Add this to wp-config.php
define('DISALLOW_FILE_EDIT', true);

Recommendation
Enable this on almost every live site.

DISALLOW_FILE_MODS disables installs and updates in wp-admin

What it does
Disables all file changes in wp-admin, including:
Installing plugins
Installing themes
Updating plugins
Updating themes
Updating WordPress core

Why it matters for security
If an attacker gets admin access, they cannot use wp-admin to install a plugin or theme as a persistence method.

Block installs on production
define('DISALLOW_FILE_MODS', true);

Allow installs temporarily
define('DISALLOW_FILE_MODS', false);

Where to add these lines
Open wp-config.php and add them above the line:
That’s all, stop editing

Example snippet for a locked down live site
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true);

Turning security into a practical workflow
Restricting installs works best when you also decide how changes will happen.

Option 1: Maintenance window toggle
Best for solo site owners who do occasional updates.
Default state on production:
DISALLOW_FILE_MODS is true

When you need to change plugins:

  1. Set DISALLOW_FILE_MODS to false.
  2. Install or update what you need.
  3. Set it back to true.

Keep the window short. Do not leave it open.

Option 2: Staging first workflow


Best for freelancers and client sites.

  1. Keep production locked with DISALLOW_FILE_MODS true.
  2. Install and update plugins on staging.
  3. Test the site pages, forms, checkout, and logins.
  4. Push changes to production via your host tool, File Manager, or FTP.
  5. Keep production locked.

Option 3: Developer workflow with WP-CLI
Best for teams that manage sites on servers they control.

  1. Lock wp-admin file changes with DISALLOW_FILE_MODS true.
  2. Update plugins with WP-CLI during maintenance windows.
  3. Restrict SSH access to trusted users only.
  4. Keep backups and a rollback plan.

Idea: you can have the flag turn on or off conditionally and based on series of IP addresses. that way you can safely and conveniently update your plugins and themes but by default they won't be allowed.

// wp-config.php (place above: "That's all, stop editing!")

$whitelisted_ips = [
    // '11.22.33.44',
    // '22.33.44.55',
];

$is_whitelisted =
    (defined('WP_CLI') && WP_CLI) ||
    (
        !empty($_SERVER['REMOTE_ADDR']) &&
        in_array(trim($_SERVER['REMOTE_ADDR']), $whitelisted_ips, true)
    );

// If whitelisted: allow installs/updates. Otherwise: block.
defined('DISALLOW_FILE_MODS') || define('DISALLOW_FILE_MODS', $is_whitelisted ? false : true);

// Keep the built-in file editor disabled everywhere.
defined('DISALLOW_FILE_EDIT') || define('DISALLOW_FILE_EDIT', true);

Common mistakes that weaken security
Mistake 1: Setting DISALLOW_FILE_EDIT and thinking installs are blocked
This only disables the editor. It does not stop installs or updates.

Mistake 2: Locking installs but letting everyone keep admin access
If you have many admins, reduce the count. Use Editor roles when possible.

Mistake 3: Treating this as a complete security plan
Restricting installs reduces one risk. It does not stop account takeover.

What this protects against, and what it does not
It helps against:
One click plugin or theme backdoors after admin access
Persistence via plugin installs through wp-admin
Quick replacement of plugin files through wp-admin updates

It does not stop:
Spam content changes
SEO spam pages created through admin access
New admin users being created
Settings changes

Add the basics to support it
Strong passwords and a password manager
Two factor login
Limit admin accounts
Remove unused plugins and themes
Keep updates scheduled and tested

Client friendly policy you can copy
Plugin installs and updates are disabled on the live site for security. Changes are applied through staging after testing, or during scheduled maintenance windows.

Quick checklist
For most live sites
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true);

For sites still in build mode
define('DISALLOW_FILE_EDIT', true);
Leave DISALLOW_FILE_MODS off until launch

For developers using WP-CLI
Lock wp-admin with DISALLOW_FILE_MODS
Restrict SSH access
Update during maintenance windows

Subscribe to our newsletter

Sharing is caring!

Do you need a learn WordPress? Learn by doing now!
This code shared in this post/site is provided "AS IS" without any warranties or guarantees of any kind. The authors and distributors of this code cannot be held responsible for any damage, data loss, or other issues that may arise from its use. It is strongly recommended that you test this code in a staging environment before deploying it to a live site. Always ensure you have proper backups and understand the implications of running this code on your WordPress installation. Use at your own risk.

Leave a Comment

Your email address will not be published. Required fields are marked *