Writing secure code in WordPress and preventing the most common security vulnerabilities

The number of vulnerabilities discovered in WordPress plugins and themes is quite impressive. If you take a look at public exploits databases, you’ll see new vulnerabilities discovered every week.

According to the most recent data (source: ThreatPress WordPress plugins and themes vulnerabilities database), the most common vulnerabilities in WordPress plugins and themes are XSS (Cross-site Scripting) and CSRF (Cross-Site Request Forgery). Less common types of vulnerabilities are SQL Injection, RFI (Remote File Inclusion), LFI (Local File Inclusion), Arbitrary File Upload, Directory Traversal.

Security is one of the most important things to keep in mind. If you develop WordPress plugins and themes, then you should follow the best security practices (See WordPress Codex: Validating Sanitizing and Escaping User Data). There are plenty of examples about every vulnerability exploitation. If you are not familiar with such types of attacks, then I’d recommend watching step by step guides on Youtube.

How to prevent attacks and secure your code in WordPress?

Validate data. Use the right helper functions to sanitize and escape data.

Validation – Verification that something is correct or conforms to a certain standard (such as a string contains numbers and letters).
Sanitization – Is a technique to modify the input to ensure that it is valid (such as doubling single quotes).
Escaping – Converting the special HTML characters to HTML entities (makes certain characters like ‘, “, and > don’t break anything and to prevent XSS).

The difference between sanitizing and escaping is that when you save something to the database, then you sanitize all data collected from $_POST, $_GET and $_REQUEST. When you output data from the database or from user input, then you escape it.

What is XSS (Cross-site Scripting) and how to prevent it?

An XSS vulnerability enables attackers to inject client-side scripts into web pages viewed by users. The first thing you need to do is to sanitize user input. In many cases you can use sanitize_text_field( $string ) function. This function will convert HTML characters to entities, strip all tags and remove extra whitespace. If you need to sanitize email, then you should use sanitize_email( $email ). For the full list of functions, go to WordPress Codex > Data Validation. When you need to output your data – escape it. It will also prevent XSS vulnerabilities. WordPress has a few helper functions such as esc_attr(), esc_html(), esc_url() and more (see Codex).

What is CSRF (Cross-Site Request Forgery) and how to prevent it?

Cross-site request forgery (CSRF) is an attack vector that tricks a web browser into executing an unwanted action in an application to which a user is logged in. To prevent CSRF, you need to use nonces. A nonce is a “number used once” to help protect URLs and forms from particular types of misuse.

How to prevent SQL injection?

Use only safe $wpdb API methods to insert, update and delete from the database. All data in SQL queries must be SQL-escaped before the SQL query is executed. A good function for that is esc_sql().

Safe methods are:
$wpdb->insert()
$wpdb->update()
$wpdb->delete()

Use other methods only with $wpdb->prepare(). This helps prevent SQL injections.