beyond the wordpress 5 minute install

36
Beyond the 5-minute Install Steve Taylor http://sltaylor.co.uk [email protected] @sltayloresque WordCamp Portsmouth UK 2011

Upload: steve-taylor

Post on 08-May-2015

5.305 views

Category:

Technology


1 download

DESCRIPTION

The slides for the talk I gave at WordCamp Portsmouth UK 2011, 16/7/11. It basically covers some security and best practices hints and tips that aren't part of the standard WordPress installation.

TRANSCRIPT

Page 1: Beyond the WordPress 5 minute Install

Beyond the 5-minute InstallSteve Taylor

http://[email protected]@sltayloresque

WordCamp Portsmouth UK 2011

Page 2: Beyond the WordPress 5 minute Install

Security & best practices

● .htaccess

● wp-config.php

● robots.txt

● functions.php / “functionality plugin”

● Plugins

● Other issues?

Page 3: Beyond the WordPress 5 minute Install

A bit about me● Custom theme developer

● No themes released

● A few plugins

This talk● Advice for beginners

● Tips for developers

Page 4: Beyond the WordPress 5 minute Install

.htaccess

● “hypertext access”

● Controls requests to server before any PHP / WordPress processing

● Apache only (IIS?)

● Root of website (sub-directories?)

● Sometimes simple, sometimes complex!

http://httpd.apache.org/docs/

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/

Page 5: Beyond the WordPress 5 minute Install

www or not www?

● Personal choice / aesthetics

● Both should be accessible; one should redirect (301) to the other

● Tell Google Webmaster Tools!

Page 6: Beyond the WordPress 5 minute Install

www or not www?

# Force no “www”RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

● Personal choice / aesthetics

● Both should be accessible; one should redirect (301) to the other

● Tell Google Webmaster Tools!

Page 7: Beyond the WordPress 5 minute Install

www or not www?

# Force no “www”RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

● Personal choice / aesthetics

● Both should be accessible; one should redirect (301) to the other

● Tell Google Webmaster Tools!

# Force “www”RewriteCond %{HTTP_HOST} ^example\.com$ [NC]RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

Page 8: Beyond the WordPress 5 minute Install

Protect important files

●# Protect .htaccess files<Files .htaccess>

order allow,denydeny from all

</Files>

●# Protect wp-config.php<Files wp-config.php>

order allow,denydeny from all

</FilesMatch>

Page 9: Beyond the WordPress 5 minute Install

WordPress pretty permalinks

Page 10: Beyond the WordPress 5 minute Install

WordPress pretty permalinks

●# BEGIN WordPress<IfModule mod_rewrite.c>RewriteEngine OnRewriteBase /RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteRule . /index.php [L]</IfModule># END WordPress

Include at end of .htaccess:

Page 11: Beyond the WordPress 5 minute Install

WordPress pretty permalinks

Really bad idea for big sites:

Page 12: Beyond the WordPress 5 minute Install

WordPress pretty permalinks

Really bad idea for big sites:

http://ottopress.com/2010/category-in-permalinks-considered-harmful/

http://codex.wordpress.org/Using_Permalinks

Better:

Page 13: Beyond the WordPress 5 minute Install

wp-config.php

● Create your own wp-config-sample.php

● Check the file for new stuff in new versions of WordPress

● Edit and initialize BEFORE installing WordPress!

http://codex.wordpress.org/Editing_wp-config.php

http://digwp.com/2010/08/pimp-your-wp-config-php/

Page 14: Beyond the WordPress 5 minute Install

Server-dependent settings

●// ** MySQL settings - You can get this info from your web host ** ///** The name of the database for WordPress */define('DB_NAME', 'database_name_here');

●/** MySQL database username */define('DB_USER', 'username_here');

●/** MySQL database password */define('DB_PASSWORD', 'password_here');

●/** MySQL hostname */define('DB_HOST', 'localhost');

Page 15: Beyond the WordPress 5 minute Install

Server-dependent settings

●switch ( $_SERVER['HTTP_HOST'] ) {case 'dev.example.com': {

// Dev serverdefine( 'DB_NAME', 'aef4RgX_mysitedev' );define( 'DB_USER', 'aef4RgX_mysitedev' );define( 'DB_PASSWORD', 'Jyt6v48jS9frkGgZyS5iIjif6LnosuYr' );define( 'DB_HOST', 'localhost' );break;

}default: {

// Live serverdefine( 'DB_NAME', 'sd6FE2xc_mysitelive' );define( 'DB_USER', 'sd6FE2xc_mysitelive' );define( 'DB_PASSWORD', 'as3d56JvDlPisYwU7c1nfZ3Yct0NEiZR' );define( 'DB_HOST', 'localhost' );break;

}}

https://www.grc.com/passwords.htm

Page 16: Beyond the WordPress 5 minute Install

Authentication Keys and Salts

define('AUTH_KEY', 'put your unique phrase here');define('SECURE_AUTH_KEY', 'put your unique phrase here');define('LOGGED_IN_KEY', 'put your unique phrase here');define('NONCE_KEY', 'put your unique phrase here');define('AUTH_SALT', 'put your unique phrase here');define('SECURE_AUTH_SALT', 'put your unique phrase here');define('LOGGED_IN_SALT', 'put your unique phrase here');define('NONCE_SALT', 'put your unique phrase here');

https://api.wordpress.org/secret-key/1.1/salt/

Change them for every installation!

Page 17: Beyond the WordPress 5 minute Install

Database table prefix

$table_prefix = 'wp_';

The default:

Page 18: Beyond the WordPress 5 minute Install

Database table prefix

$table_prefix = 'wp_';

$table_prefix = 'a3rfGtQ1_';

The default:

Much better:

Page 19: Beyond the WordPress 5 minute Install

Database table prefix

When coding database queries, don’t use hard-coded table names!

Page 20: Beyond the WordPress 5 minute Install

Database table prefix

global $wpdb;$custom_query = $wpdb->get_results( “SELECT ID, post_title FROM

$wpdb->posts” );

When coding database queries, don’t use hard-coded table names!

A standard WP table:

Page 21: Beyond the WordPress 5 minute Install

Database table prefix

global $wpdb;$custom_query = $wpdb->get_results( “SELECT ID, post_title FROM

$wpdb->posts” );

When coding database queries, don’t use hard-coded table names!

A standard WP table:

http://codex.wordpress.org/Class_Reference/wpdb

global $wpdb;$custom_query = $wpdb->get_results( “SELECT field FROM ” .

$wpdb->prefix . “table” );

A custom table:

Page 22: Beyond the WordPress 5 minute Install

Server needs FTP for upgrades?

define( "FTP_HOST", "ftp.example.com" );define( "FTP_USER", "myftpuser" );define( "FTP_PASS", "hQfsSITtKteo1Ln2FEhHlPkXZ" );

Page 23: Beyond the WordPress 5 minute Install

Debugging

define( 'WP_DEBUG', true );

Page 24: Beyond the WordPress 5 minute Install

Debugging

define( 'WP_DEBUG', true );

●switch ( $_SERVER['HTTP_HOST'] ) {case 'dev.example.com': {

// Dev serverdefine( 'WP_DEBUG', isset( $_GET['debug'] ) );break;

}default: {

// Live serverdefine( 'WP_DEBUG', false );break;

}}

http://dev.example.com/?debug=1

Page 25: Beyond the WordPress 5 minute Install

Control revisions and autosave

// Only keep 3 revisions of each postdefine( 'WP_POST_REVISIONS', 3 );

Page 26: Beyond the WordPress 5 minute Install

Control revisions and autosave

// Only keep 3 revisions of each postdefine( 'WP_POST_REVISIONS', 3 );

// Don’t keep revisions of postsdefine( 'WP_POST_REVISIONS', false );

Page 27: Beyond the WordPress 5 minute Install

Control revisions and autosave

// Autosave posts interval in secondsdefine( 'AUTOSAVE_INTERVAL', 60 );

// Only keep 3 revisions of each postdefine( 'WP_POST_REVISIONS', 3 );

// Don’t keep revisions of postsdefine( 'WP_POST_REVISIONS', false );

Page 28: Beyond the WordPress 5 minute Install

Disable plugin and theme editing

define( 'DISALLOW_FILE_EDIT', true );

Page 29: Beyond the WordPress 5 minute Install

robots.txt

http://codex.wordpress.org/Search_Engine_Optimization_for_WordPress#Robots.txt_Optimization

User-agent: *Disallow: /wp-adminDisallow: /wp-includesDisallow: /wp-content/pluginsDisallow: /wp-content/cacheDisallow: /wp-content/themesDisallow: /trackbackDisallow: /feedDisallow: /commentsDisallow: /category/*/*Disallow: */trackbackDisallow: */feedDisallow: */commentsDisallow: /*?*Disallow: /*?Allow: /wp-content/uploads

Sitemap: http://example.com/sitemap.xml

Page 30: Beyond the WordPress 5 minute Install

Custom theme functions.php / “functionality” plugin

● Snippets not worth making into a plugin

● Plugin is more portable

● Check out /mu-plugins/

http://justintadlock.com/archives/2011/02/02/creating-a-custom-functions-plugin-for-end-users

http://wpcandy.com/teaches/how-to-create-a-functionality-plugin

http://codex.wordpress.org/Must_Use_Plugins

Page 31: Beyond the WordPress 5 minute Install

Disable upgrade notifications for people who can't do upgrades

if ( ! current_user_can( 'update_core' ) ) {add_action( 'init', create_function( '$a', "remove_action( 'init',

'wp_version_check' );" ), 2 );add_filter( 'pre_option_update_core', create_function( '$a', "return

null;" ) );}

Page 32: Beyond the WordPress 5 minute Install

Remove nofollow from comments

remove_filter( 'pre_comment_content', 'wp_rel_nofollow' );add_filter( 'get_comment_author_link', 'slt_dofollow' );add_filter( 'post_comments_link', 'slt_dofollow' );add_filter( 'comment_reply_link', 'slt_dofollow' );add_filter( 'comment_text', 'slt_dofollow' );function slt_dofollow( $str ) {

$str = preg_replace('~<a ([^>]*)\s*(["|\']{1}\w*)\s*nofollow([^>]*)>~U','<a ${1}${2}${3}>', $str );

return str_replace( array( ' rel=""', " rel=''" ), '', $str );}

}

http://digwp.com/2010/04/wordpress-custom-functions-php-template-part-2/

Page 33: Beyond the WordPress 5 minute Install

Better default display names

add_action( 'user_register', 'slt_default_user_display_name' );function slt_default_user_display_name( $user_id ) {

$first = get_usermeta( $user_id, 'first_name' );$last = get_usermeta( $user_id, 'last_name' );$display = $first . " " . $last;wp_update_user( array( "ID" => $user_id, "display_name" => $display )

);}

Page 34: Beyond the WordPress 5 minute Install

Plugins

Force Strong Passwords. Copies WordPress's JavaScript password strength meter into PHP and forces “executive” users to have a strong password when updating their profile.http://wordpress.org/extend/plugins/force-strong-passwords/

Google XML Sitemaps (or equivalent).http://wordpress.org/extend/plugins/google-sitemap-generator/

Use Google Libraries.http://wordpress.org/extend/plugins/use-google-libraries/

WordPress Database Backup.http://wordpress.org/extend/plugins/wp-db-backup/

Page 35: Beyond the WordPress 5 minute Install

Other issues

● File permissionshttp://codex.wordpress.org/Hardening_WordPress#File_permissions

● .htpasswd for /wp-admin/

● Settings > Discussion

Page 36: Beyond the WordPress 5 minute Install

Cheers!

http://sltaylor.co.uk

@sltayloresque