Block PHP Execution in the Uploads Folder (Apache)
Adds Tools > Uploads Protection with a button that writes .htaccess rules to your uploads folder so PHP files there can never be run, even if one slips through an upload.
Opens WPIDE on
Code
add_action( 'admin_menu', function () {
add_management_page( 'Uploads Protection', 'Uploads Protection', 'manage_options', 'wpide-uploads-protection', function () {
require_once ABSPATH . 'wp-admin/includes/misc.php';
$uploads = wp_get_upload_dir();
$file = trailingslashit( $uploads['basedir'] ) . '.htaccess';
$marker = 'WPIDE: no PHP in uploads';
if ( isset( $_POST['wpide_protect_uploads'] ) && check_admin_referer( 'wpide_protect_uploads' ) && current_user_can( 'manage_options' ) ) {
$ok = insert_with_markers( $file, $marker, array(
'<FilesMatch "\.(?i:php\d?|phtml|phar|pht|phps)$">',
' Require all denied',
'</FilesMatch>',
) );
printf( '<div class="notice notice-%s"><p>%s</p></div>', $ok ? 'success' : 'error', $ok ? 'Rules written.' : 'The .htaccess file could not be written. Check folder permissions.' );
}
$active = in_array( 'Require all denied', extract_from_markers( $file, $marker ), true );
echo '<div class="wrap"><h1>Uploads Protection</h1>';
echo '<p>Status: <strong>' . ( $active ? 'PHP execution is blocked in uploads.' : 'Not protected yet.' ) . '</strong></p>';
echo '<form method="post">';
wp_nonce_field( 'wpide_protect_uploads' );
submit_button( $active ? 'Write the rules again' : 'Block PHP in uploads', 'primary', 'wpide_protect_uploads' );
echo '</form></div>';
} );
} );
Notes
Works on Apache and LiteSpeed; on Nginx add a location rule for /wp-content/uploads/ that denies .php files instead.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.