A Denial-of-Service (DoS) attack from Facebook?

The other day I got an automated alert from our managed WordPress hosting service, notifying me of an issue with resource exhaustion for a virtual site. Upon closer inspection, I discovered that the adversary was not your everyday aimless botnet, but something darker, and far more sinister.

Facebookexternalhit

Your assumptions are wrong - To err is human (image credit u/EvanOfTheYukon)

The WordPress site in distress was under attack from Facebook’s crawler and had received more than 2000 requests in a couple of minutes. I’ve never seen traffic like this from Facebook before, so apparently, something has gone off the rails somewhere.

The Facebook Crawler crawls the HTML of a website that was shared on Facebook via copying and pasting the link or by a Facebook social plugin on the website. The crawler gathers, caches, and displays information about the website such as its title, description, and thumbnail image.

Source: Facebook for developers.

Finding the issue

By examining the server log, I could determine that the issue was most likely caused by the website owner accidentally sharing a post’s URL that was only accessible from the WordPress dashboard. This seems to have caused the Facebook crawler to go into berserker mode after failing to get by the WordPress login screen.

What followed was a remarkable and neverending redirect loop where the crawler would seemingly try to dissect the shared URL by removing the last character on each subsequent request. This would continue until the resources for the virtual site had been thoroughly exhausted.

The customer’s point of view

I did talk to the site owner to obtain additional information, but I was unable to get anything useful other than a confirmation that the wrong URL might have been shared on their Facebook profile. I don’t have a Facebook account myself, so that’s where my quest ended.

Disappointingly, I found that placing the blame with Facebook for the issues my customer had experienced with their website was a tough sell. I have a sneaking suspicion they blame me instead.

We told you not to crawl that

On the topic of disappointing, why is the Facebook crawler requesting resources from a /wp-admin/ path when all crawlers are prohibited from doing so by robots.txt?

The contents of robots.txt (default WordPress):

User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php

Oh well, I guess Facebook doesn’t have to play by the same rules as the rest of us.

The log extract

The following is an extract of the first few lines from the server log containing the abnormal requests. All crawler traffic originated from 31.13.64.0/18.

"GET /wp-admin/post.php?post=2310&action=edit HTTP/1.1" 301 278 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=edit HTTP/1.1" 302 - "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=edit HTTP/1.1" 302 - "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A%2F%2Fdomain.tld%2Fwp-admin%2Fpost.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A%2F%2Fdomain.tld%2Fwp-admin%2Fpost.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=edit HTTP/1.1" 301 278 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=edit HTTP/1.1" 302 - "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=edit HTTP/1.1" 302 - "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A%2F%2Fdomain.tld%2Fwp-admin%2Fpost.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A%2F%2Fdomain.tld%2Fwp-admin%2Fpost.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-login.php?redirect_to=http%3A//domain.tld/wp-admin/post.php%3Fpost%3D2310%26action%3Dedit&reauth=1 HTTP/1.1" 206 2427 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=edi HTTP/1.1" 301 277 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=ed HTTP/1.1" 301 276 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=e HTTP/1.1" 301 275 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action= HTTP/1.1" 301 274 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action HTTP/1.1" 301 273 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&actio HTTP/1.1" 301 272 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&acti HTTP/1.1" 301 271 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&act HTTP/1.1" 301 270 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&ac HTTP/1.1" 301 269 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&a HTTP/1.1" 301 268 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310 HTTP/1.1" 301 262 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=231 HTTP/1.1" 301 261 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2 HTTP/1.1" 301 259 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=23 HTTP/1.1" 301 260 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post= HTTP/1.1" 301 258 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post HTTP/1.1" 301 257 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?pos HTTP/1.1" 301 256 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?po HTTP/1.1" 301 255 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php HTTP/1.1" 301 252 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php HTTP/1.1" 301 252 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?p HTTP/1.1" 301 254 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.ph HTTP/1.1" 301 251 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/pos HTTP/1.1" 301 247 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/po HTTP/1.1" 301 246 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post HTTP/1.1" 301 248 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/p HTTP/1.1" 301 245 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.p HTTP/1.1" 301 250 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin HTTP/1.1" 301 244 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin HTTP/1.1" 301 243 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admi HTTP/1.1" 301 242 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-ad HTTP/1.1" 301 240 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-adm HTTP/1.1" 301 241 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp- HTTP/1.1" 301 238 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-a HTTP/1.1" 301 239 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp HTTP/1.1" 301 237 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /w HTTP/1.1" 301 236 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin HTTP/1.1" 301 244 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=edi HTTP/1.1" 301 277 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=ed HTTP/1.1" 301 276 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action HTTP/1.1" 301 273 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action=e HTTP/1.1" 301 275 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&action HTTP/1.1" 301 273 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&actio HTTP/1.1" 301 272 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&act HTTP/1.1" 301 270 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&acti HTTP/1.1" 301 271 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&ac HTTP/1.1" 301 269 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310 HTTP/1.1" 301 262 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=231 HTTP/1.1" 301 261 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2 HTTP/1.1" 301 259 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=2310&a HTTP/1.1" 301 268 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?po HTTP/1.1" 301 255 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post HTTP/1.1" 301 257 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post=23 HTTP/1.1" 301 260 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?post HTTP/1.1" 301 257 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php HTTP/1.1" 301 252 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?pos HTTP/1.1" 301 256 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php HTTP/1.1" 301 252 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.ph HTTP/1.1" 301 251 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)"
"GET /wp-admin/post.php?p HTTP/1.1" 301 254 "-" "facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php

I would be interested to learn if anybody else has experienced this kind of traffic from Facebook.