Alert When wp-config.php, .htaccess or Root Files Change
Checks your site's root folder once a day and emails the administrator when wp-config.php, .htaccess, .user.ini or php.ini change, or when new PHP files appear next to WordPress's own files.
Opens WPIDE on
Code
$wpide_root_snapshot = function () {
$root = ABSPATH;
$files = array();
foreach ( (array) glob( $root . '{*.php,.htaccess,.user.ini,php.ini}', GLOB_BRACE ) as $path ) {
if ( is_file( $path ) ) {
$files[ basename( $path ) ] = md5_file( $path );
}
}
$config = dirname( ABSPATH ) . '/wp-config.php';
if ( ! isset( $files['wp-config.php'] ) && is_file( $config ) ) {
$files['../wp-config.php'] = md5_file( $config );
}
return $files;
};
add_action( 'init', function () {
if ( ! wp_next_scheduled( 'wpide_root_files_check' ) ) {
wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', 'wpide_root_files_check' );
}
} );
add_action( 'wpide_root_files_check', function () use ( $wpide_root_snapshot ) {
$now = $wpide_root_snapshot();
$old = get_option( 'wpide_root_files' );
update_option( 'wpide_root_files', $now, false );
if ( ! is_array( $old ) ) {
return;
}
$lines = array();
foreach ( array_diff_key( $now, $old ) as $file => $hash ) {
$lines[] = 'New file: ' . $file;
}
foreach ( array_diff_key( $old, $now ) as $file => $hash ) {
$lines[] = 'Removed: ' . $file;
}
foreach ( array_intersect_key( $now, $old ) as $file => $hash ) {
if ( $old[ $file ] !== $hash ) {
$lines[] = 'Changed: ' . $file;
}
}
if ( $lines ) {
wp_mail( get_option( 'admin_email' ), sprintf( '[%s] Files in the site root changed', wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) ), implode( "\n", $lines ) . "\n\nCore updates change some of these files; if you did not update WordPress or edit them, check them now." );
}
} );
Notes
Core files are covered by WordPress checksums; this watches the configuration files and unexpected additions that those checks miss.
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.