Friday, 26 May, 2017 UTC


Summary

This article is part of a series created in partnership with SiteGround. Thank you for supporting the partners who make SitePoint possible.
With 27% of the web using WordPress, security is the #1 concern for anyone running their website on this mega popular open source platform. Although the security of WordPress core is looked after by a dedicated team of developers, the same cannot be said of all the thousands of third-party plugins and themes that extend WordPress to make it do pretty much anything you want. Just one vulnerable plugin or theme can represent a high risk for millions of sites.
In this article, I'm going to introduce a few guidelines and WordPress functions you can apply in your WordPress theme development to ensure your products are coded with users' security at their very core.
Principles of Security-Minded Developers
For dedicated WordPress plugin and theme developers, security is at the top of their mind in every line of code they write.
A serious overall approach to coding safe WordPress themes includes paying attention to the following general principles:
  • Consider all data insecure until proven otherwise
  • Use WordPress functions whenever possible. Most WordPress APIs have built-in security mechanisms, which means using them puts your code at a much lower risk of being open to vulnerabilities
  • Keep your code up-to-date with the latest technologies and best practices.
What You Need to Watch Out For
The most common threats you need to watch out for are:
  • SQL injections: an attacker injects malicious SQL code to take control of a website's database server
  • Cross site scripting (XSS): an attacker injects malicious JavaScript code into a web page
  • Cross-site Request Forgery (CSRF): an attacker forces users to perform undesired actions on a website where they are authenticated.
Web security is always evolving, therefore it's important to stay current on the latest threats. Where WordPress is concerned, the Sucuri blog is a great place to learn about vulnerabilities and attacks.
Data Validation, Sanitization and Escaping
Before accepting any input data from any source, e.g., users, web services, APIs, etc., you must check that it is what you expect it to be and that it's valid. This task is called validation.
For instance, if you collect users' emails via a form on your website, your code needs to check if users have entered some text input (not some number or nothing at all, for example) and that the input corresponds to a valid email address before entering that data into the database.
You might think this kind of check would hardly be required in a theme. In fact, forms are better included using a plugin rather than a theme. However, this is not entirely the case. If you plan on adding theme options via the Customizer, for example, you might need to perform some data validation on users' input.
Sanitizing consists in filtering or cleaning data coming from users, web services, etc., that it's about to be stored in the database. During this process, you can remove anything that could be harmful or undesired from the data, e.g., JavaScript statements, special characters, etc.
Escaping consists in making sure the data is safe to display, e.g., removing special characters, encoding HTML characters, etc. The recommended practice here is to escape as late as possible, just before displaying the data on the screen.
You'll need to do a lot of sanitization and escaping in WordPress themes. In fact, to be on the safe side, the best bet is to sanitize/escape all dynamic data, i.e., any data that is not hard-coded in the HTML source.
WordPress Validation Functions
You can perform basic validation using a number of handy PHP functions.
For instance, to check if a variable doesn't exist or has a value set to false, you can use empty().
However, to make validation a breeze, WordPress offers these useful functions.
  • You can check if the data is a valid email address by using the is_email( $email ) function.
    For example:
    [code language="php"]
    if ( is_email( '[email protected]' ) ) {
    echo 'valid email address.';
    }
    [/code]
  • To check for valid usernames, WordPress makes available username_exists( $username ):
    [code language="php"]
    $username = 'testuser';
    if ( username_exists( $username ) ):
    echo "Username exists.";
    endif;
    [/code]
  • To make sure a tag, category, or other taxonomy term exists, you can use term_exists( $term, $taxonomy = '', $parent = null ):
    [code language="php"]
    //check if the category cats exists
    $term = term_exists('cats', 'category');
    if ($term !== 0 && $term !== null) {
    echo "The 'cats' category exists.";
    }
    [/code]
  • To ensure a file path is valid (but not if it exists), use validate_file( $file, $allowed_files ):
    [code language="php"]
    $path = 'uploads/2017/05/myfile.php';
    // returns 0 (valid path)
    return validate_file( $path );
    [/code]
WordPress Sanitization/Escaping Functions
Continue reading %Coding Safe Themes with Built-In WordPress Functions%