Make WordPress Core

Opened 17 years ago

Closed 11 years ago

Last modified 11 years ago

#4137 closed defect (bug) (fixed)

Pingback Denial of Service possibility

Reported by: foobarwp12's profile foobarwp12 Owned by: nacin's profile nacin
Milestone: 3.6 Priority: low
Severity: normal Version: 1.5
Component: Security Keywords: needs-patch
Focuses: Cc:

Description

The pingback feature of Wordpress (2.1.3) allows DDOS attacks either against the server hosting wordpress or against a third one.

When a client sends a pingback, wordpress calls "wp_remote_fopen" to download the referring URL. On servers having "allow_url_fopen" activated, this function will try to download the /whole/ URL without any timeout or size limit. (except those set in php.ini, which will usually lead to a ~8MB download)

So if you post ~100 xmlrpc requests referring to a /huge/ file, every server meeting those prerequisites should effectively be down (for a while). You should at least be able to generate lots of traffic.

On the other hand, if you google for blogs and post the same URL to each of 'em, the target server should be DDOSed.

I suggest allowing pingbacks only if the connection was opened from the host mentioned in the source URL.

I'll attach a demo exploit (I didn't test it for the entered URL; it worked for a local installation.)

Attachments (4)

exploit.py (751 bytes) - added by foobarwp12 17 years ago.
Exploit
4137-functions.patch (878 bytes) - added by pishmishy 17 years ago.
Patch to fix wp_remote_fopen()s use when allow_url_fopen
4137-functions-curl.patch (2.2 KB) - added by pishmishy 17 years ago.
potential fix for issue when curl is used?
4137-functions-new.patch (2.2 KB) - added by pishmishy 17 years ago.
patch improved with suggestions

Download all attachments as: .zip

Change History (35)

@foobarwp12
17 years ago

Exploit

#1 @foolswisdom
17 years ago

  • Milestone changed from 2.0.eventually to 2.2
  • Version set to 2.1.3

#2 @rob1n
17 years ago

  • Milestone changed from 2.2 to 2.3
  • Owner changed from anonymous to rob1n

We'll put this in for 2.3.

#3 @rob1n
17 years ago

  • Owner rob1n deleted

#4 in reply to: ↑ description @pishmishy
17 years ago

  • Owner set to pishmishy
  • Status changed from new to assigned
  • Summary changed from Pingback DDOS possibility to Pingback Denial of Service possibility

Replying to foobarwp12:

I suggest allowing pingbacks only if the connection was opened from the host mentioned in the source URL.

This is a tricky one. I think this suggestion will break for URLs where the host name is an alias for another host as the URL's hostname might be completely different to the hostname of the system where the pingback request comes from.

Setting a limit the size of the download wouldn't completely remove the amplification effect (the limit would have to be less than the size of the xmlrpc request) but it is what the Pingback specification recommends.

I've changed the name of this ticket - there is the potential for a distributed denial of service here but the real issue is the amplification in bandwidth leading to a traditional denial of service attack.

@pishmishy
17 years ago

Patch to fix wp_remote_fopen()s use when allow_url_fopen

#5 @pishmishy
17 years ago

  • Keywords has-patch 2nd-opinion added

The attachment fixes the problem when allow_url_fopen has been set but doesn't fix the problem when curl is used to fetch the source page. I believe that this case can be fixed using callbacks but my PHP isn't up to the task. I'm opening that part up to others.

@pishmishy
17 years ago

potential fix for issue when curl is used?

#6 @pishmishy
17 years ago

  • Keywords needs-testing added

This second attachment contains a potential fix for the issue when using curl to fetch the pages. It feels ugly to me but I hope that it should do the trick. I've only tested the function outside of WordPress and it does appear to be able to limit the number of bytes fetched with curl but how well it plays with WordPress I wouldn't like to guess.

#7 @Otto42
17 years ago

You may want to set the CURLOPT_RANGE parameter as well. On servers that support it (HTTP 1.1, some FTP's), it will limit the server to only returning the amount of data you want. On those that don't support it, it won't have any effect.

I would also suggest setting CURLOPT_BUFFERSIZE (only for PHP5 and up) to some value like 4096 or something. I think the default action of curl in the way you're using it will simply retrieve the whole page and return it to your read function as a single string, or as some really large buffer or something.

Using a CURLOPT_TIMEOUT of some value, like 30-60 seconds, would also limit the impact from this sort of thing.

Essentially, there's no certain way to make curl stop retrieving data. But these would at least help.

@pishmishy
17 years ago

patch improved with suggestions

#8 @pishmishy
17 years ago

Sorry for the delay in an updated patch, been on holiday. I've amended the patch with Otto42's suggestions.

#9 @ryan
17 years ago

  • Milestone changed from 2.3 to 2.4 (next)

#10 @josephscott
16 years ago

  • Cc josephscott added

#11 @lloydbudd
16 years ago

  • Milestone changed from 2.5 to 2.6

#12 @Denis-de-Bernardy
15 years ago

any traction on this one?

#13 @Denis-de-Bernardy
15 years ago

  • Keywords xmlrpc ddos possibility removed

#14 @ryan
15 years ago

  • Keywords has-patch removed
  • Milestone 2.9 deleted
  • Priority changed from high to low
  • Resolution set to wontfix
  • Status changed from assigned to closed

Patch no longer applies now that we moved to WP_Http.

There are so many ways to orchestrate a DDOS, I don't know if this is worth bothering with. If someone feels otherwise, re-open with a patch that works with WP_Http.

#15 @wycks
11 years ago

  • Cc bob.ellison@… added
  • Keywords needs-testing removed
  • Resolution wontfix deleted
  • Severity changed from normal to minor
  • Status changed from closed to reopened
  • Version 2.1.3 deleted

This might be worth looking into again as there is now a ready made script taking advantage of the Pingback API that will most likely be bundled for the script kiddie's.

https://github.com/FireFart/WordpressPingbackPortScanner

#16 @toscho
11 years ago

  • Cc info@… added

#17 @F J Kaiser
11 years ago

  • Cc 24-7@… added

#18 @F J Kaiser
11 years ago

  • Keywords needs-patch added; 2nd-opinion removed
  • Severity changed from minor to normal

#19 @dh-shredder
11 years ago

  • Cc dh-shredder added

#20 @SergeyBiryukov
11 years ago

  • Milestone set to Awaiting Review
  • Version set to 1.5

#21 @TJNowell
11 years ago

  • Cc tom@… added

#22 @soficgr
11 years ago

  • Cc soficgr@… added

I agree with wycks. Famous news blog in my country today talking about this.
I think must go to minor again. There are so many ways to do DDOS, is true (not need wp for this). But this is famous for wp and has script. Matt said this summer "we chose two, stability and security for wp" in video and i really liked it, many people don't understand what is this "simply read in a blog and then panic".

#23 @iandunn
11 years ago

  • Cc ian_dunn@… added

#24 @scribu
11 years ago

  • Cc scribu added

#25 @kovshenin
11 years ago

  • Cc kovshenin added

#26 @pishmishy
11 years ago

Can someone remind me how I 'unown' a ticket. I'm afraid I haven't got time to devote to this and I don't want it to look like I'm continuing to take ownership when that's clearly not the case.

#27 @ocean90
11 years ago

  • Owner pishmishy deleted
  • Status changed from reopened to reviewing

#29 @nacin
11 years ago

  • Owner set to nacin
  • Resolution set to fixed
  • Status changed from reviewing to closed

In 24870:

Limit pingback response size. fixes #4137.

#30 @nacin
11 years ago

In 24871:

Limit pingback response size. fixes #4137. for trunk.

#31 @nacin
11 years ago

  • Milestone changed from Awaiting Review to 3.6
Note: See TracTickets for help on using tickets.