Welcome to part seven of our website security series! In previous installments, we discussed how all websites are targets, and that there’s no such thing as perfect security. We talked about how securing the platform websites run on is a 24/7/365 commitment.
If you have made it this far, you have an overview of the most serious threats to web content management systems, security recommendations for Drupal, and how to securely update WordPress. Now let’s talk about securing WordPress for day-to-day operations.
Secure WordPress Administration
Once you’ve made sure you have a rock-solid WordPress update strategy, the next thing to take care of is securing the admin area and user accounts. Follow these steps to move your site closer to the “safer” side of the security continuum:
Don’t use “Admin” as the admin username. Many attacks look for the WordPress default username “admin” for the admin account. So when you set up your site, make sure to choose a different username. If you already have an established site, you can manually change the name or use a plugin to change it.
Use strong passwords. We all know we’re supposed to use passwords that are hard to crack (and hard to remember). So why are the most popular passwords “123456,” “password,” and “12345678?” Use robust passwords for all user accounts. If you don't have one already, use a service like LastPass to store strong passwords securely.
Don’t share passwords. This should go without saying...but, sadly, it doesn’t. Each user should have their own account and private password. And, for that matter, don’t store passwords in a google doc, in a Word doc, or on a sticky note on your monitor.
Always use HTTPS. It’s not a luxury add-on item anymore. If your site is collecting and storing any kind of personally identifiable information (PII), it should be secured. Services like Cloudflare and Let’s Encrypt can get you started.
Choosing WordPress Plugins
As a general rule, only use plugins that come from a trusted, verifiable source, and make sure to keep them up-to-date. Avoid sites that offer free knockoffs of premium plugins; frequently, they have vulnerabilities either accidentally or maliciously introduced into the code.
The barrier of entrance to plugin development is low, so your plugin selection strategy is key to ensuring your site remains secure. Mitigate risk by reaching out to the greater WordPress community and trusted maintainers—or better yet, consult with a professional WordPress developer or agency—when considering any community plugins for your site.
That said, there are a number of things that everyone should know about choosing plugins. The Make WordPress Training section on plugins recommends reviewing a plugin's Star Rating, Last Updated, Number of Downloads, Compatibility Rating, Author Information and Support Forum activity. If you’re unsure about how to best evaluate any of these things, WPBeginner has a good article that goes into more detail on how to best select plugins.
Improving Security Through Plugins
In addition to choosing plugins wisely, there are a number of plugins that specifically seek to improve the security of your site, including:
iThemes Better Security has over 30 ways to lock down WordPress, including protecting login attempts, forcing SSL, disabling file editing and more.
BulletProof Security is another suite with many tools including some nice options like idle session logout and modification of login cookie expiration length.
VaultPress is a subscription service offering realtime backup, automated security scanning, and support from WordPress experts.
Login Lockdown helps to prevent brute force password discovery by limiting the number of failed login attempts from specific IP addresses.
Two-Factor is a feature plugin for core that provides Two-Factor Authentication.
Force Strong Passwords forces privileged users to set a strong password.
Secure WordPress Coding
The last major aspect of WordPress security is not creating exploitable vulnerabilities in your own code. As covered in part four, there are three types of common attacks that all WordPress developers need to understand how to protect against: Cross-Site Scripting (XSS), SQL Injection, and Cross-Site Request Forgery (CSRF).
Closing XSS Vulnerabilities
In a recent study of nearly 1600 WordPress plugin vulnerabilities, security firm Wordfence found XSS was the most common vulnerability. The XSS vulnerability made up half of all vulnerabilities found:
*Image from Wordfence
XSS enables attackers to execute malicious code into web pages viewed by other users. XSS vulnerabilities usually arise when a form can accept arbitrary user input, which is then passed to the database without being sanitized.
Avoid XSS attacks by using functions to validate your data. Wordfence has an in-depth rundown of the types of XSS vulnerabilities in WordPress and how to close them.
Closing SQL Injection Vulnerabilities
SQL injection means that attackers can enter SQL commands into a SQL statement through an input form on your web page. SQL injection attacks can fill your database with spam, drop your data, or steal sensitive information.
*Image from BAE Systems
Fortunately, SQL injection attacks are well-understood and easy to prevent. It’s a simple matter of properly sanitizing data, whether through prepared statements or escaping user-supplied input. The OWASP SQL Injection cheat sheet has a detailed explanation of how to prevent SQL vulnerabilities in any web application.
WordPress has lots of function to help with sanitizing and escaping user data. Validating Sanitizing and Escaping User Data codex article is the place to start getting familiar with these practices and the Data Validation page of the WordPress Codex has all the functions to use.
When working with the database it's best to use WordPress' built-in classes, such as WP_Query. If you must do direct database queries be sure to use the wpdb class. The codex page for wpdb has great info on protecting queries against SQL injection attacks.
If you would like some history on one of the biggest undertakings by the WordPress security team Andrew Nacin gave a great talk called Anatomy of a Critical Security Bug. Post Status also has a great write up of the vulnerability if you prefer an article to a video.
Closing CSRF Vulnerabilities
XSS attacks rely on the reputation of your website to fool a user. CSRF attacks rely on a trusted user to fool your website. Usually it involves tricking a logged-in user into clicking a link that does something the user didn’t intend to do.
*Image from Divergent Thought Blog
Fortunately, WordPress has a built-in function to help stop CSRF attacks. This function is called a “nonce,” which stands for “numbers used once.” These numbers are like passkeys that are specific to a user and session, and change at an interval you set. Any information submitted that looks like it comes from the user must have a matching nonce or it will be rejected.
This article from CSS-Tricks has a good explanation of how to use nonces, including how to generate and validate them.
WordPress nonces are a bit different than the traditional nonce.WordPress nonces aren't numbers, but are a hash made up of numbers and letters. They also have a limited lifetime, during which the same nonce will be generated for a given user in a given context.
WordPress nonces help protect against several types of attacks including CSRF, but do not protect against replay attacks because they aren't checked for one-time use. Nonces should never be relied on for authentication or authorization, access control. Protect your functions using current_user_can(), and assume Nonces can be compromised.
In WordPress nonces are tied to actions and are intended to help prevent users from accidently performing an action from a malicious link. The WordPress developer handbook article on nonces says "Nonces can be used to check that the current user actually intends to perform the action selected."
For example, as a WordPress administrator you could be tricked into clicking on a link that would normally delete a blog post. If the link came from outside WordPress it likely won't include a nonce and therefore not be valid.
If you'd like to read more Mark Jaquith, a WordPress core developer, has a great post on WordPress nonces.
Only You Can Keep Your WordPress Sites Secure
It only takes a few small, easy steps to move your WordPress site up the security continuum. Start with common-sense measures to protect your admin accounts: rename “admin” and practice good password hygiene. Then use trusted plugins to add another layer of security. Finally, make sure your code treats all user-entered data as a potential threat: Sanitize, escape, and validate.
Once your platform and your site are secure, there’s only one layer of security left to tackle. And it’s a big one: It’s the human beings that make up your organization. In the last post of the series, we’ll focus on the operations and processes that will help everyone in your agency develop a security mindset. Stay tuned!
This is the 7th post in a series of articles on website security. Read the rest:
- Part 1: You Are A Target
- Part 2: Website Security Isn’t Binary
- Part 3: Security in the Platform Layer
- Part 4: The Application Layer
- Part 5: Securing Drupal
- Part 6: Updating WordPress Securely
- Part 7: Administering WordPress
- Part 8: Organization Processes