trust no one (WordPress security)

Jonathan Williams (wcfay, @johnwilliams, links, all presentations)

“Developing for open-source software is generous and optimistic… but when you talk about security, you have to consider the world your enemy.”
— John Williams

Codex Links

The User

  • Whatever your password is, it sucks.
  • Whenever you last changed your WordPress password, it probably was too long ago.
  • 1Password is a god-send. So is LastPass.
  • Secure your WP admin traffic in wp-config.php with the following constants:
  • Questions for any user input:
    • What is being submitted? What is the user supposed to be submitting?
    • Where is it coming from?
    • Where is it supposed to be output/displayed? What’s the proper context for the data?


  • Validate input by ensuring data is in expected format
    • Insist on a format, e.g. typecast integers using (int) or force text with preg_replace, stripping out any non-alpa characters (^[a-z]/i).
    • Whitelist approved input (pre-defined acceptable values), throwing away (or setting to a default) anything that doesn’t match.
    • Use nonces (wp_nonce_field, wp_verify_nonce) to verify origin of data.
    • Use the WordPress Settings API when you are making custom plugins or themes.
  • Sanitize output by ensuring data is safe to display (script injection)
    • wp_kses — strip bad html tags from output by whitelisting approved tags (this is what strips paragraph tags from the editor)
    • esc_html — avoid scripting attacks
    • $wpdb — lots of built in validation and sanitization functions
    • Need custom admin meta boxes? Why not Meta Box?
  • Escape by ensuring data cannot trigger sql injection

The Server

  • Buy private hosting. It’s worth it.
  • Stop using FTP. Use key-based SFTP/SSH.