As suggested in this question, I am adding this topic as a new question, for community discussion/voting regarding best-practices for Plugin/Theme security.
Here is the starting checklist, based on my current (work-in-progress) settings/data security checklist used for reviewing Themes (the principles should be no different for Plugins than they are for Themes).
If you want to check out a theme with a secure and solidly-coded theme settings page, check out this theme:
http://wordpress.org/extend/themes/coraline
Use Nonces (when not using Settings API)
Plugins and Themes should explicitly provide Settings-page nonce checking, if not using the Settings API:
Sanitize, validate and escape data
Sanitize anything that could get in and out of (!) the database both front end and back end!
Plugins and Themes should perform proper data validation:
into the database
fields
Escape all untrusted data before being output in the Theme template
files
Plugins and Themes should use
esc_attr()
for text inputs andesc_html()
oresc_textarea()
for text areas.Also available from the WordPress API is
esc_url()
,esc_url_raw()
,esc_js()
andwp_filter_kses()
.Bad example:
Good example:
Here is a great video of Mark Jaquith explaining the usage of the escaping functions:
Only use $_GET / $_POST / $_REQUEST carefully and when better APIs are unavailable
Plugins and Themes should use the Settings API to get and save form input data rather than rely on
$_POST
and$_REQUEST
data directly.Use
$wpdb->prepare
When building custom queries via the
$wpdb
object, always use$wpdb->prepare
to fill placeholders with values instead of writing the queries with data mixed with SQL code, as themysql_*
family functions have wrongly taught everyone.Be careful with PHP functions that might be used to run malicious code
A nice read for anybody writing PHP: Exploitable PHP functions on StackOverflow.
Use Theme Modification API
Themes should use
set_theme_mod()
and related functions not an self invented name scheme.The theme_mod API is a specialized layer for the settings API; it guarantees unique names, pushes all options into one array and is â from my experience â much easier to handle. Plus, it offers standardized filters for plugins â which is good for interoperability.
Avoid enabled
register_globals
Donât rely on
register_globals = on
. A Pro Theme which my last client bought does exactly this. I could hack any site using this theme in 5 minutes â¦ThimbThumb did this too (and still does?).
Do not create files with unnecessary wide access permissions
Donât create files with too liberate access permissions.
Use SSL where available
Point your Share on Twitter/Facebook/Anything links to the HTTPS URI if available. Your readerâs security is important too.
Save data in single array
Plugins and Themes should save options in a single array, rather than create multiple options for the settings page. The use of the Settings API would handle this.
Check for appropriate capability when adding and outputting settings pages
Plugins should use an appropriate capability (e.g.
manage_options
) for the capability to add the settings page.Themes should use
edit_theme_options
as the appropriate capability to add the settings page.Use up-to-date tutorials and information
Plugins & Themes should both implement Options and Settings pages deliberately and not rely on copy-and-paste website tutorials which are outdated and do not include proper data security, such as those listed below.
Examples of what not to do:
How to create an options page for your wordpress theme (1stwebdesigner.com)
Create an awesome WordPress theme options page part 1 (wpshout.com)
Use Settings API
Plugins and Themes should use the Settings API, which is easier to use, more secure, and takes care of a lot of the hard work of settings pages:
For a good tutorials on using the Settings API, see:
For checkboxes and select options, Plugins and Themes should use the
checked()
andselected()
functions for outputtingchecked="checked"
andselected="selected"
, respectively.Prefix function and variable names
Plugins should prefix all options, custom functions, custom variables, and custom constants with plugin-slug.
Themes should prefix all options, custom functions, custom variables, and custom constants with theme-slug.
Use wp_safe_redirect() instead of calling php’s header() function directly when directing to a page on the same domain.
Add settings pages to appropriate sections of admin menu
Plugins should use the
add_options_page()
function to add the Plugin Settings Page to theSettings
menu, rather than usingadd_menu_page()
to add a top-level menu.Themes should use the
add_theme_page()
function to add the Theme Settings Page to theAppearance
menu, rather than usingadd_menu_page()
to add a top-level menu.