The above graph shows recent statistics of WordPress vulnerability from WPScan Vulnerability Database summarized by Sucuri which is a worldwide security company especially famous for analyzing vulnerability in WordPress.
Why so many vulnerabilities are there in WP plugins?
After reading the Sucuri Blog deeply and widely, I came to the conclusion that there is some kind of disuse and misuse of WordPress core functions.
I’d like to verify each vulnerability from this point of view.
Unfortunately, XSS is very popular in WordPress plugins. In many cases, this occur with insufficient validation of untrusted data which comes from the outside (including from the DB) and lack of an escape just before responding to the user agent. The latter is a fundamental countermeasure.
|GET parameter||<a href="…?value=
|SRC/HREF attribute||<iframe src="
|CSS Value||<div style="width:
You already know about this very well?
Sure, in case of Blubrry PowerPress <= 6.0, XSS had already taken into account. The following statistics shows before and after fixing XSS.
In fact, those patches could be seen everywhere in their codes. Those were hard to track before and after. Moreover,
esc_html()were mixed and used.
esc_html(), the third parameter of
htmlspecialchars() is specified more strictly than their codes. I could hardly say that’s OK or not, but using core functions is always OK.
I think this issue is caused by disuse and misuse of WordPress core functions.
Also, it’s important to design codes to separate “Validating Input” in “Model” and “Escaping Output” in “View”. I’m not saying about MVC here. But codex says to use “Validating Sanitizing and Escaping User Data” along with the context. So every developer should design the context at first.
In August 2014, Sucuri reported about SQLi in Custom Contact Forms.
The following snippet from CCF (<= 188.8.131.52) dumps the set of SQL queries and downloads the previous one.
adminInit() was no doubt for the administrators. But this snippet had at least next five issues:
- Validate user role by
- Lack of consideration of unexpected access route.
- Export and import without validating user privilege.
- Export raw SQL to the client.
- Import raw SQL from the client.
As a result, an attacker could easily know the DB prefix defined in the
wp-config.php with a certain attack vector and could inject some malicious SQL to exploit the site.
This was caused by misuse of
is_admin() which is always
true when someone accesses the admin area even without authentication.
To avoid this vulnerability, the developer must follow the SQL Injection Prevention Cheat Sheet like below:
- Validate user privilege by
- Validate nonce to limit the access route.
- Export and import validated and parameterized queries.
- Use stored procedures.
- Escape all user-supplied input.
On February 3, 2015, Sucuri disclosed PE in UpdraftPlus plugin <= 1.9.50.
Suppose a registered user hits a button on the dashboard to do something.
wp-admin/?action=foo is requested, the function
foo_handler will be triggered via the action hook
admin_action_foo by the following code:
foo-secret-nonce is also used in a function for an administrator to do an important job and only
check_admin_referer('foo-secret-nonce') is examined without validating user privilege, a PE will happen.
Exactly the same vulnerability in WPtouch (<= 3.4.2) was also disclosed on July 14, 2014.
This is caused by the disuse of WordPress nonce.
The cause of CSRF is simple.
For example, if you click “Save Changes” on the admin screen, the page transition happens after saving the setting data into the DB. In a sequence of these processes, if no nonce is on the page before the transition or no validation of nonce before saving data, CSRF immediately occurs.
In this case, only validation of user authentication or privilege at the saving process is not enough to prevent this vulnerability because an administrator potentially clicks a malicious link with their own authorized cookie.
Such disuse of nonce leads many plugins to CSRF.
FI (or Arbitrary File Download) is a vulnerability that occurs by giving the user-supplied input to some file system functions such as
file_get_contents()without proper validation.
In September 2014, the vulnerability of Slider Revolution became a big topic. By requesting a certain functionality for an administrator, an attacker could download any files via a request to
admin-ajax.php like this:
This request was handled with:
- No validation of user privilege.
- No validation of nonce.
- No validation of given input.
As a result, the attacker could easily download
wp-config.php without knowing the user name and password.
We can find this kind of vulnerability in the old version of HD FLV Player. In this plugin,
download.php was called directly regardless of WordPress context where we should follow its event-driven programming style to use appropriate functions for validating a nonce and user privilege.
I’ve found a lot of disuse and misuse of WordPress core functions in Sucuri Blog and conclude the following for developing WordPress plugins and themes :-).
- Input has been contaminated.
- The DB has also been contaminated.
- Secret information may leak.
- Administrator privileges also may leak and be stolen.
- Attacks may come from an unexpected route.
- The attacker actually doesn’t access the page.
And I quite agree with James Golovich:
If you have the WordPress tools available to you then you should use them.
Something like current_user_can() and a nonce should always be used.