Wordpress

XML RPC Disable

XML-RPC is a WordPress feature that enables the transfer of data between WordPress and other systems. It has now been largely replaced by REST API but is still included in installations for backwards compatibility.

If it is enabled on WordPress, an attacker can perform brute force, pingback (SSRF) attacks, etc.

  • For Apache

XML-RPC can be disabled by adding/(creating a .htaccess file) with below lines in .htaccess file on WordPress’s root directory.

<Files xmlrpc.php>
order deny,allow
deny from all
</Files>
  • If you want to use this feature, you can allow an IP.
<Files xmlrpc.php>
order deny,allow
deny from all
allow from 192.168.1.101
</Files>
  • For Nginx

XML-RPC can be disabled by adding below lines in nginx.config.

location ~* ^/xmlrpc.php$ {
return 403;
}
  • With the use of the plugin, XMP RCP can be disabled. There is a plugin to disable XML RPC.

References

https://www.wpbeginner.com/plugins/how-to-disable-xml-rpc-in-wordpress/

https://kinsta.com/blog/xmlrpc-php/

https://blogvault.net/wordpress-disable-xmlrpc/

https://www.malcare.com/blog/wordpress-disable-xmlrpc/


User Enumeration Via JSON File

WordPress includes a REST API that can be used to list the information about the registered users on a WordPress installation. The REST API exposed user data for all users who had authored a post of a public post type. WordPress 4.7.1 limits this to only post types which have specified that they should be shown within the REST API.

References

https://www.jinsonvarghese.com/prevent-wordpress-username-enumeration/


User Enumeration Via author Parameter

If permalinks are enabled, in many WordPress installations it is possible to enumerate all the WordPress usernames iterating through the author archives. Whenever a post is published, the username or alias is shown as the author. For example, the URL http://wordpress_site.com/?author=1 will show all the posts from user id 1. Attackers can abuse this functionality to figure out which usernames are available on the site.

  • This can be prevented by adding a few lines in .htaccess file.
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_URI}  ^/$
RewriteCond %{QUERY_STRING} ^/?author=([0-9]*)
RewriteRule ^(.*)$ http://yoursite.com/? [L,R=301]
</IfModule>

References

https://www.acunetix.com/vulnerabilities/web/wordpress-username-enumeration/


Brute Force Attack at Login Page.

To prevent brute force attack at the login page, you will need to add the following configuration in apache, IIS and Nginx config files.

  • For Apache

This attack can be prevented by adding below lines in .htaccess file.

ErrorDocument 401 default

  • For IIS

This attack can be prevented by adding below lines in web.config file.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  </system.webServer>
    <!-- Existing Configuration Excluded -->
    <location path="wp-login.php" overrideMode="Allow">
        <system.webServer>
            <security>
                <authentication>
                    <anonymousAuthentication enabled="false" />
                    <windowsAuthentication enabled="true" />
                </authentication>
            </security>
        </system.webServer>
    </location>
</configuration>
  • For Nginx

This attack can be prevented by adding below lines in nginx.config file.

error_page 401 http://yourwordpress.com/wp-admin/wp-login.php


Limit Access to wp-login.php by IP

If you want to log in to the admin area of the WordPress then you can white list your IP to log in to the WordPress application.

  • For Apache

Add the following lines in .htaccess file.

# Block access to wp-login.php.
<Files wp-login.php>
  order deny,allow
  allow from 203.0.113.15
  deny from all
</Files>

If you want to add more than one IP address, you can add the following lines in .htaccess file:

# Block access to wp-login.php.
<Files wp-login.php>
  Require ip 203.0.113.15 203.0.113.16 203.0.113.17
  # or for the entire network:
  # Require ip 203.0.113.0/255.255.255.0
</Files>
  • For IIS

Add the following lines in the web.config file.

<location path="wp-admin">
  <system.webServer>
    <security>
      <ipSecurity allowUnlisted="false"> <!-- this rule denies all IP addresses, except the ones mentioned below -->
        <!-- 203.0.113.x is a special test range for IP addresses -->
        <!-- replace them with your own -->
        <add ipAddress="203.0.113.15" allowed="true" />
        <add ipAddress="203.0.113.16" allowed="true" />
      </ipSecurity>
    </security>
  </system.webServer>
</location>
  • For Nginx

Add the following lines for one and more than one IP in nginx.config file.

error_page  403  http://example.com/forbidden.html;
location /wp-login.php {
  allow   203.0.113.15
  # or for the entire network:
  # allow   203.0.113.0/24;
  deny    all;
}

Plugins to Prevent Brute Force Attack.

Following plugins can help to prevent brute force attack.

  • Limit Login Attempts Reloaded
  • SiteGuard WP Plugin
  • Brute Force Login Protection
  • WordPress Login & Security, Anti Hacker Plugin
  • Loginizer
  • Change wp-admin login

References

https://wordpress.org/support/article/brute-force-attacks/

https://wordpress.org/plugins/tags/brute-force/

https://wordpress.org/plugins/search/admin+rename/


Injection Attacks

SQL Injection (SQLi)

All data in SQL queries must be SQL-escaped before the SQL query is executed to prevent SQL injection attacks. WordPress provides helper classes to assist with escaping SQL queries $wpdb.

Selecting Data

The escaped SQL query ($sql in this example) can then be used with one of the methods:

  • $wpdb->get_row($sql)
  • $wpdb->get_var($sql)
  • $wpdb->get_results($sql)
  • $wpdb->get_col($sql)
  • $wpdb->query($sql)

Inserting and Updating Data

  • $wpdb->update($sql)
  • $wpdb->insert($sql)

Like Statements

  • $wpdb->prepare($sql)

Cross-Site Scripting (XSS)

Escaping is the process of securing output by stripping out unwanted data, like malformed HTML or script tags, preventing this data from being seen as code.

Escaping helps secure your data before rendering it for the end-user and prevents XSS (Cross-site scripting) attacks.

WordPress has a few helper functions you can use for most common scenarios.

esc_html() – Use this function anytime an HTML element encloses a section of data being displayed.

<?php echo esc_html( $title ); ?>

esc_url() – Use this function on all URLs, including those in the src and href attributes of an HTML element.

<img src="<?php echo esc_url( $great_user_picture_url ); ?>" />

esc_js() – Use this function for inline Javascript.

<a href="#" onclick="<?php echo esc_js( $custom_js ); ?>">Click me</a>

esc_attr() – Use this function on everything else that’s printed into an HTML element’s attribute.

<ul class="<?php echo esc_attr( $stored_class ); ?>"> </ul>

esc_textarea() – encodes text for use inside a textarea element.

<textarea><?php echo esc_textarea( $text ); ?></textarea>

Escaping with Localization Rather than using echo to output data, it’s common to use the WordPress localization functions, such as _e() or __().

These functions simply wrap a localization function inside an escaping function:

esc_html_e( 'Hello World', 'text_domain' );
// same as
echo esc_html( __( 'Hello World', 'text_domain' ) );

These helper functions combine localization and escaping:

  • esc_html__()
  • esc_html_e()
  • esc_html_x()
  • esc_attr__()
  • esc_attr_e()
  • esc_attr_x()

Note: Whenever you’re outputting data make sure to properly escape it.

References

https://developer.wordpress.org/themes/theme-security/data-sanitization-escaping/

https://developer.wordpress.org/themes/theme-security/data-validation/


Note

  • If other vulnerabilities occur in Themes and Plugins, you can follow our PHP Recommendation to prevent those vulnerabilities since WordPress is built on PHP.