WordPress Themes: XSS Vulnerabilities and Secure Coding Practices
As many might imagine, my life revolves around Information Security. If you’re like me, you’re undoubtedly seeing all these new posts talking to insecurities in WordPress themes, specifically a plethora of Cross-Site Scripting (XSS) vulnerabilities. Surprise, surprise, right? Yeah, no, not so much.
Here are some of the posts I am referring to:
- F-Secure – WordPress Premium Theme XSS Vulnerability
- PC Magazine – More XSS Vulnerabilities Found in WordPress Themes
- Sophos Threatpost – Some WordPress Themes, Thousands of Sites Open to XSS Vulnerability
So what’s the big deal? Honestly, not much. It’s the same thing that has plagued other development groups for years. What’s perhaps most frustrating is that these are simple mistakes, especially when it comes to WordPress.
I recently attended a SANS course in Las Vegas, SANS Network Security 2012. In it the instructor said if there is anything you can do, as a developer, it’s to perform Explicit Error Checking. If you accept 5 characters, then verify both the size and character set. Fundamentally the principle and advise is simple and sound, and the kicker is it’d help address not just Cross-Site Scripting attacks but OS Command injection, Buffer overflows, and SQL injection attacks.
But saying that is one thing, implementing is another. Being that the time to write about each would be too exhaustive, let’s look at WordPress specifically. Before we do, let’s understand this thing called Cross Site Scripting.
Before we can implement corrections to a problem, we have to understand the problem. So what is this thing known as XSS? We can turn our head to The Open Web Application Security Project for an official definition. This is how they describe it:
Cross-Site Scripting attacks are a type of injection problem, in which malicious scripts are injected into the otherwise benign and trusted web sites. Cross-site scripting (XSS) attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user.
An example of this would be if you found a website that asked you for username and password, or even your address and you typed in something like this:
But, what if I did something like this:
So what can you do about it in WordPress? Well, let’s talk about that.
Leveraging Built-In WordPress Functions
To help with this, I’m going to reference a very very good video by Mark Jaquith at WordCamp Phoenix 2011 on Theme & Plugin Security. I will also reference things presented at WordCamp San Francisco 2011 at the Plugin Security Showdown with Mark Jaquith, Jon Cave and Brad Williams.
To keep this post to a reasonable size I’m going to focus solely on the recommendations to address XSS issues, but please note that there are many other attack vectors that should be looked into and it’s highly recommended you watch the videos also.
Escape late – do it as close to the potential vulnerability point as possible. If you escape before that you’re likely to lose track of what is safe and what is not. – Mark Jaquith
Another exceptional post on Data Sanitization and Validation with WordPress was put out by Stephen Harris with WPTuts. In it he provides three very simple rules, same as those used in the videos:
- Rule No. 1: Trust Nobody
- Rule No. 2: Validate on Input, Escape on Output
- Rule No. 3: Trust WordPress
- Rule No. 4: Making Data Safe is About Context
In Harris’s post he goes into much more detail for each rule. Specifically the input validation which is just as important as the output, but here we’ll reference out-of-the-box functions that come with WordPress.
As of 2.8, WordPress introduced new functions that make it easier to escape. They all start with esc_. If you’re not familiar with them you can always find them in the codex here: http://codex.wordpress.org/Function_Reference/.
Here is a quick list of them as well:
- esc_html() – Be mindful when using this one, it kills html, so if you require html like features, think widgets, wp_filter_kses() is the function to use
- esc_attr() – As implied by the name, this is designed to escape attributes.
- esc_url() – This is used to print url’s to the page.
- esc_url_raw() – This is used to save url’s to the database or to redirect.
- esc_js() – Supersedes js_escape() and used when you are printing JS to the page.
- esc_textarea() – This is designed specifically for use with textareas, it double encodes entities making it more effective for textarea’s.
- wp_filter_kses() – allows you to use safe HTML, html sanitization library
What’s important to note about these escape functions is that they reference whitelist libraries. Whitelist libraries are fundamentally better than a blacklist library which are exceptionally hard to maintain. Hopefully this helps some of you, if nothing else it should help build your awareness around the built-in WordPress functions designed to help you build more secure products.
If you have any questions about this post please leave us a comment or send us an email firstname.lastname@example.org.