Table of Contents
Where possible, data must be validated on input.
Any data being added to the system from external sources, such as user input or an external API, must be validated to ensure that the data is as expected. For example, if an email address is expected then the is_email() function can be used to check that the data received is a valid email address.
Although validation may occur on the client side, this cannot be solely relied on. The data also needs to be revalidated on the server side before the data is saved.
For more information on validation, refer to Data Validation article.
If data cannot be validated on input, it must be sanitized instead.
Any data being added to the system from external sources that cannot be validated must be sanitized. For example, it may not be possible to validate a text field, instead, it should be sanitized using the sanitize_text_field() or wp_kses() functions.
For more information on sanitization, refer to Data Sanitization/Escaping article.
Working with the Database
Themes must not work directly with the database to create, update or delete site content and should generally only use WordPress core functions to display content.
If there is a valid reason to work with the database, then the wpdb class provided by WordPress must be used. SQL statements must be prepared using $wpdb->prepare(). When using a LIKE expression, $wpdb->esc_like() must be used before preparing the SQL statement.
For more information, refer to the following resources:
All dynamic data must be escaped on output, whether it comes from the user, the database, variables or from an external source.
Whenever content is rendered, it must be escaped properly for the context in which it is rendered. For example, when outputting a URL, esc_url() must be used to ensure that no malicious data is output.
Escaping should occur as late as possible, ideally at the output. If for some reason it is not possible to escape at the output, then a comment must be left in the code noting where the variable has been escaped.
It is recommended that the escaped data be stored in a variable that has _escaped as a suffix.
// This variable has been safely escaped in the following file: themename/directory/file.php Line: 123
<div id=”somediv”><?php echo $data_escaped; ?></div>
WordPress core functions that return dynamic data must be escaped by the theme, except for those core functions starting with 'the_', which are generally escaped already. For example, home_url, admin_url, get_permalink, get_header_image, etc., should be escaped, but the_content, the_permalink, etc., are not required to be escaped.
All translated strings must be escaped to avoid outputting malicious or malformed code that has been added to a .mo file. Use the functions provided by WordPress to do this, including: esc_html__(), esc_html_e(), esc_html_x(), esc_attr__(), esc_attr_e(), esc_attr_x().
For more information on escaping data, refer to Securing Output article.
User capabilities must be checked for appropriateness before any data is submitted to the server.
Only users with the appropriate capabilities may be allowed to submit data to the server. For example, a contributor must not be able to change the theme options. The current_user_can() function can be used to check whether the current user has the appropriate capabilities.
For more information on user capabilities, refer to Checking User Capabilities article.
Any data that is submitted to the server must use nonces.
If a user is allowed to submit data to the server, a nonce must be used to verify the origin and intent of the request. The nonce must be set in the form or link used to submit the data and must then be checked on the server side before the data is processed. For example, a nonce must be set on the theme options form and then checked on the server before the settings are saved.
For more information on nonces, refer to Nonces article.
Themes must not enable SVG uploads as it raises security concerns due to the possibility of attackers executing malicious code through SVG’s XML.
For more information on SVG uploads, refer to SVG uploads in WordPress article.
All releases containing a security fix must be clearly flagged as a security fix in the Changelog.
For further information on writing secure code, refer to the following articles: