Improve WordPress security (.htaccess)
# Enable .htpasswd authentication
<If "%{HTTP_HOST} != 'dev'">
AuthType Basic
AuthName "Login to dashboard"
AuthUserFile /path/to/.htpasswd
Require valid-user
</If>
# Deny access to all .htaccess files
<Files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</Files>
# Deny access to wp-config.php file
<Files wp-config.php>
order allow,deny
deny from all
</Files>
# Disable directory browsing
Options ALL -Indexes
# Disable access to all file types except the following
Order deny,allow
Deny from all
<Files ~ ".(xml|css|js|jpe?g|png|gif|pdf|docx|rtf|odf|zip|rar)$">
Allow from all
</Files>
# Block wp-includes folder and files
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
# Prevent image hotlinking script. Replace last URL with any image link you want.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?mywebsite.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ http://i.imgur.com/MlQAH71.jpg [NC,R,L]
</IfModule>
# Setup browser caching
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 2 days"
</IfModule>
# Restrict PHP file execution
<Directory "/var/www/wp-content/uploads/">
<Files "*.php">
Order Deny,Allow
Deny from All
</Files>
</Directory>
# Protect site against script injections
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
</IfModule>
# Prevent username execution
RewriteCond %{QUERY_STRING} author=d
RewriteRule ^ /? [L,R=301]
# Require SSL
SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "www.mywebsite.com"
ErrorDocument 403 https://www.mywebsite.com
Improve WordPress security (.htpasswd)
# Enable .htpasswd authentication (see also http://www.htaccesstools.com/htpasswd-generator/)
username:password
Disable XML-RPC pingbacks and methods (functions.php)
//* Remove X-Pingback header
add_filter( 'wp_headers', function( $headers ) {
unset( $headers['X-Pingback'] );
return $headers;
}, 20);
//* Remove XML-RPC methods
add_filter( 'xmlrpc_methods', function( $methods ) {
unset( $methods['pingback.ping'] );
unset( $methods['pingback.extensions.getPingbacks'] );
return $methods;
}, 20);
Hide all login errors (functions.php)
//* Hide all login errors
add_filter( 'login_errors', 'nl_hide_login_errors' );
function nl_hide_login_errors(){
return null;
}
Disable embed script (functions.php)
//* Disable embed script
add_action('init', 'nl_disable_wp_embed');
function nl_disable_wp_embed() {
if (!is_admin()) {
wp_deregister_script('wp-embed');
}
}
Disable emojis (functions.php)
//* Disable the emoji's
add_action( 'init', 'nl_disable_wp_emojis' );
function nl_disable_wp_emojis() {
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
add_filter( 'tiny_mce_plugins', 'nl_disable_wp_emojis_tinymce' );
}
//* Remove emoji's from tinymce
function nl_disable_wp_emojis_tinymce( $plugins ) {
if ( is_array( $plugins ) ) {
return array_diff( $plugins, array( 'wpemoji' ) );
} else {
return array();
}
}
Remove query strings (functions.php)
//* Remove query strings
add_filter( 'script_loader_src', 'nl_remove_query_strings', 15, 1 );
add_filter( 'style_loader_src', 'nl_remove_query_strings', 15, 1 );
function nl_remove_query_strings( $src ){
$parts = explode( '?ver', $src );
return $parts[0];
}
Add link shortcode to widget title (functions.php)
//* Add link shortcode to widget title
//* Usage: [link href = https://www.google.com]Google[link]
add_filter( 'widget_title', 'link_widget_title' );
function link_widget_title( $title ) {
$title = str_replace( '[link', '<a', $title );
$title = str_replace( '[/link]', '</a>', $title );
$title = str_replace( ']', '>', $title );
return $title;
}
Add page slug as id to widget title (functions.php)
//* Add page slug as id to widget title
add_filter('widget_title', 'add_slug_id_to_widget_title', 15, 3);
function add_slug_id_to_widget_title($title, $instance, $args){
$page = get_page_by_title($title);
$title = sprintf('<span id="%s">%s</span>', $page->post_name, $title);
return $title;
}
Add taxonomies to post type page (functions.php)
//* Add taxomonies to page
add_action( 'init', 'nl_add_taxonomies_to_pages' );
function nl_add_taxonomies_to_pages() {
register_taxonomy_for_object_type( 'post_tag', 'page' );
register_taxonomy_for_object_type( 'category', 'page' );
}
Enhance WordPress customizer (functions.php)
//* Enhance customizer
add_action( 'customize_register', 'nl_enhance_customizer' );
function nl_enhance_customizer( $wp_customize ) {
$wp_customize->add_section(
'footer_section',
array(
'title' => __('Title of the settings box', 'theme_name'),
'description' => __('Description of the settings box'),
'priority' => 150,
)
);
$wp_customize->add_setting(
'footer_textbox',
array(
'default' => __('Default value of the settings box', 'theme_name'),
)
);
$wp_customize->add_control(
'footer_textbox',
array(
'label' => __('Label of the control box', 'theme_name'),
'description' => __('Description of the control box'),
'section' => 'footer_section',
'type' => 'textarea',
)
);
}
Hide admin bar (functions.php)
//* Hide admin bar
add_filter('show_admin_bar', '__return_false');
Highlight parent menu item (functions.php)
//* Highlight parent menu item
add_action('nav_menu_css_class', 'nl_nav_menu_css_class', 10, 2 );
function nl_nav_menu_css_class($classes, $item) {
global $post;
$current_post_type = get_post_type_object(get_post_type($post->ID));
$current_post_type_slug = $current_post_type->rewrite['slug'];
$menu_slug = strtolower(trim($item->url));
if ( strpos($menu_slug,$current_post_type_slug) !== false ) {
$classes[] = 'current-menu-item active';
}
return $classes;
}