DDoS Targeting WordPress Search

This article was originally published on Sucuri blog (read here).

Have you ever stopped to think about how many resources a search engine has or if your website could handle the same amount of search traffic that Google does?

Search engines play an important role on the internet and with how websites perform. One may say that they are the actual doorway to the online world. No one can deny how many hours it saves us on a daily basis in finding exactly the information we want in a second or two. This type of speed would certainly be described as pure magic a century ago.

How Search Engines Work

In order to return the proper results, search engines must query at least one datasource extensively at lighting speed–even if for you, it’s just a blink of an eye. The structure behind the search box consists of dozens of different softwares, billions of lines of code, and uncountable servers on a giant search engine like Google or Bing. These technologies power search engines to process huge numbers of requests instantly.

By contrast, a simple website does not have the resources required to handle thousands of search queries per second. Most of the time, that website is hosted on a shared server with very limited resources to spare.

Now, imagine if the website had to handle dozens, thousands or… (scary pause)… millions of search requests!

Believe me, it’s very common, very real, and very painful. When a website can’t handle the number of requests, it has to start rejecting some of the traffic. This is known as a denial of service.

All the work you put on writing decent content only to see it unavailable–just because an attacker or random bot decided your website should face its worst nightmares.

What is DDoS?

DDoS stands for Distributed Denial Of Service, and attacks are designed to prevent legitimate users from accessing a website. For a DDoS attack to be successful, the attacker needs to send more requests than the victim server can handle. Depending on where on a website that attacker targets, even a small amount of requests can be enough to overload the server.

We just hosted a webinar that shows what a live DDoS attack looks like. Feel free to watch it.

Luckily, my dear reader, today, you are fighting back!

Warrior Photo
Warrior Photo by Henry Hustava on Unsplash

The Battle Against DDoS Targeting

Let’s assume for a moment that the requests your website receives are like these:

152.65.171.11 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=11973-18160-4434 HTTP/2.0" 200 8950 "-" "Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.12154 Safari/537.40"
32.55.10.14 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=12974-18576-27383 HTTP/2.0" 200 8955 "-" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.2; WOW64; Trident/6.0)"
159.65.156.160 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=13055-12525-19160 HTTP/2.0" 200 8955 "-" "Mozilla/5.0 (Windows NT 9.0; Win64; x64) AppleWebKit/141.36 (KHTML, like Gecko) Chrome/36 Safari/537.36"
47.55.13.13 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=13060-440-2062 HTTP/2.0" 200 8940 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/375.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.37"
201.10.17.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=13831-6592-5705 HTTP/2.0" 200 8945 "-" "Mozilla/5.0 (Windows NT 7.0; Win64; x64) AppleWebKit/144.36 (KHTML, like Gecko) Chrome/19 Safari/537.32"
45.169.67.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=14737-26600-23381 HTTP/2.0" 200 8955 "-" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"
68.183.175.2 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=14817-6999-8812 HTTP/2.0" 200 8945 "-" "Mozilla/5.0 (Windows NT 5.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/11.0 "
41.10.60.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=16747-3280-27284 HTTP/2.0" 200 8950 "-" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"
159.68.170.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=17385-12079-19913 HTTP/2.0" 200 8955 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
163.55.60.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=20176-22092-10087 HTTP/2.0" 200 8955 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/101.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/587.31"
19.156.10.165 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=20378-3097-24832 HTTP/2.0" 200 8950 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20150101 Firefox/66.0 "
186.11.60.13 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=21147-27226-26924 HTTP/2.0" 200 8955 "-" "curl/7.11.0"
14.99.11.2 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=21478-11397-31330 HTTP/2.0" 200 8955 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/126.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.12"
11.65.55.3 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=25692-23013-20062 HTTP/2.0" 200 8955 "-" "Mozilla/5.0 (Windows NT 9.0; Win64; x64) AppleWebKit/333.36 (KHTML, like Gecko) Chrome/14.0 Safari/557.01"
33.32.158.165 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=26413-23770-32319 HTTP/2.0" 200 8955 "-" "Mozilla/5.0 (compatible; bingbot/1.6; +http://www.bing.com/bingbot.htm)"
13.55.60.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=26523-9017-6348 HTTP/2.0" 200 8945 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/527.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
152.65.171.169 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=26909-30927-7354 HTTP/2.0" 200 8950 "-" "curl/7.58.0"
162.11.14.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=32112-28532-15792 HTTP/2.0" 200 8955 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/100.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"
64.16.88.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=4017-25004-8181 HTTP/2.0" 200 8945 "-" "curl/7.33.0"
122.15.158.165 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=431-14829-8710 HTTP/2.0" 200 8940 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/64.0 "
37.55.65.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=4471-10241-3399 HTTP/2.0" 200 8945 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.16 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
45.55.88.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=489-30164-14756 HTTP/2.0" 200 8945 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/532.36 (KHTML, like Gecko) Chrome/71.0.3626.121 Safari/537.36"
45.26.60.88 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=6114-31830-6800 HTTP/2.0" 200 8945 "-" "curl/7.11.0"
23.68.158.165 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=6480-3069-4171 HTTP/2.0" 200 8940 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/587.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/214.36"
14.13.60.15 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=6777-8027-10654 HTTP/2.0" 200 8945 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/12 Safari/511.36"
159.63.10.169 - - [11/Mar/2019:14:36:08 -0400] "GET /?s=8690-15927-13372 HTTP/2.0" 200 8950 "-" "curl/7.22.0"

These search requests are coming from different IP addresses and user agents–there is no pattern. You see lots of requests per second. Your website is hosted on a very limited hosting plan and resource usage is skyrocketing. Total panic mode on!

CPU and Memory Usage
CPU and Memory Usage

How to Defend Against DDoS on WordPress

Among the various strategies you could apply in your website defense, here you can find the most effective and popular ones:

1 – Disable the WP Search Feature

Close the gates of the castle by disabling WordPress search feature if your website does not need it. A good idea would be using the WordPress plugin Disable-Search.

If you don’t want to use a plugin to disable WordPress search, you can use a security rule on your .htaccess OR nginx.conf file to block access at “/?s=”, for example:

# BEGIN Block WordPress Search

RewriteEngine On
RewriteCond %{QUERY_STRING} ^s=([^&]+)$ [NC]
RewriteRule ^(.*)$ - [F,L]

# END Block WordPress Search

2 – Change the “/?s=” Query String in WordPress

Deceive the attacker by changing the “/?s=” query string as described on this WPBeginner article.

Bear in mind that the attacker can easily discover the new search URL or if the attacker is using the search box of your website as target, changing the search URL would have an effect.

3 – Apply Rate Limits to WordPress

Narrow the bridge to the castle by applying rate limits, which are rules to control the traffic. This requires a special module installed on your web server to control the traffic on a specific part of your website. You can use the modules:

    • mod_security,
    • mod_evasive,
    • ngx_http_limit_req_module

Or you can use a special software such as fail2ban. Consult with your hosting provider if you don’t know how to proceed.

It is also possible to achieve the same by using plugins on your website, but usually this would imply that the plugin would need to monitor everything that is being accessed, and thus, generate extra load on your hosting plan, which is precisely what we are trying to avoid.

4 – Replace the WordPress Search Engine

Ally with specialized ninjas by replacing the WordPress search engine with a professional search service such as AlgoliaSearchIQ or any other external professional search services.

These external services have their own infrastructure and they:

  • speed the search queries,
  • offer more filters for a refined search experience,
  • have native protection against brute force attacks.

Most of these professional search services offer a WordPress plugin that is able to replace the original search system quite smoothly, usually with a single click and no code change.

However…

If things went bananas and nothing you have tried works, it’s time to bring out the big guns! Literally.

EE-18 Sucuri - tank destroyer, yes, Sucuri’s name came from this tank
EE-18 Sucuri – tank destroyer, yes, Sucuri’s name came from this tank

5 – Use a Web Application Firewall (WAF)

Install a cloud website firewall such as the Sucuri Firewall and let it win this war for you.

A WAF is able to stop the attack right after being activated by using specially crafted filters, pattern recognition algorithms and a very powerful network.

The Sucuri Firewall offers:

  • a battle-tested technology,
  • a proactive team behind it with years of experience in the field,
  • readiness to deal with anything,
  • website protection against vulnerabilities you didn’t even know existed,
  • and much more.

Conclusion

If you followed the instructions:

  1. Disable the WP Search Feature
  2. Change the “/?s=” Query String in WordPress
  3. Apply Rate Limits to WordPress
  4. Replace the WordPress Search Engine
  5. Protect Your Website with a WAF

The battle against the WordPress search DDoS attack is probably over and you are victorious. However, if you could not follow the first 4 tips, use a WAF to protect your WordPress website against DDoS attacks.

These are simple to activate if you know how to change your DNS records. If you don’t know how, our team is happy to set it up for you. You can sign up for a free 30-day trial of the Sucuri Website Firewall.

Comments