Disable the Theme and Plugin File Editor in WordPress

The theme and plugin file editors in WordPress let any administrator change PHP files from the browser. One typo can take the site down, and a stolen admin password becomes a way to run code on the server. This snippet disables the theme and plugin file editor in WordPress, so the Theme File Editor and Plugin File Editor screens and menu items are gone for every user.

The snippet

<?php
/**
 * Disable the Theme File Editor and Plugin File Editor.
 */
if ( ! defined( 'DISALLOW_FILE_EDIT' ) ) {
	define( 'DISALLOW_FILE_EDIT', true );
}

// Safety net: deny the editor capabilities even if the constant was set to false elsewhere.
add_filter( 'map_meta_cap', 'dpc_deny_file_editors', 10, 2 );

function dpc_deny_file_editors( array $caps, string $cap ): array {
	if ( in_array( $cap, array( 'edit_themes', 'edit_plugins', 'edit_files' ), true ) ) {
		return array( 'do_not_allow' );
	}

	return $caps;
}

How it works

  • DISALLOW_FILE_EDIT is the switch WordPress reads in map_meta_cap(). When it is true, the edit_themes, edit_plugins and edit_files capabilities map to do_not_allow for everyone, and the editor menus and screens disappear.
  • The if ( ! defined() ) guard avoids a “Constant already defined” warning when wp-config.php or the host already sets it. The older One-Click Import version called define() without the guard.
  • The map_meta_cap filter is the safety net: if the constant was defined as false somewhere else, the filter still denies the three capabilities.
  • Installing, activating and updating plugins and themes keep working.

Add it with Scripts Organizer

In Scripts Organizer go to Code Blocks → Add New and give the block a name. Set Trigger location to Everywhere, tick PHP under Script location, paste the code into the PHP editor and publish. Leave Action/Hook empty. Everywhere code is loaded while Scripts Organizer itself loads, before WordPress checks any capability, so the constant is in place in time. Admin only would also hide the screens, but Everywhere keeps the capabilities denied in every kind of request.

The best home for the constant is still wp-config.php, above the “That’s all, stop editing!” line. Use the code block when you can’t edit wp-config.php.

The same code also works unchanged in a small plugin or an mu-plugin.

For more hardening, see Lockdown Admin Backend to your IP and WordPress Security Updates Email Alert Without a Plugin.

Gotchas

  • Scripts Organizer is a code editor too, and this snippet does not restrict it. Limit administrator accounts to people you trust.
  • Disabling the code block, or deactivating Scripts Organizer, brings the file editors back. If that matters, set the constant in wp-config.php, where only someone with file access can remove it.
  • DISALLOW_FILE_MODS goes further and also blocks installing and updating plugins and themes from the dashboard. Use it only when updates come from Git or your host.
  • On multisite the editors are already limited to super admins; the snippet removes them for super admins as well.

In the Scripts Organizer library Import it with one click from Scripts Organizer.

// newsletter

Three tested WordPress snippets a week

Blocks, security, performance, Tailwind, PHP and React. Copy, paste, ship. You’ll also get DPlugins product updates. No spam, and you can unsubscribe anytime.

// newsletter

Three tested WordPress snippets a week

Blocks, security, performance, Tailwind, PHP and React. Copy, paste, ship. You'll also get DPlugins product updates. No spam, and you can unsubscribe anytime.