WordPress.org

Make WordPress Core

Opened 3 months ago

Last modified 3 months ago

#43320 new enhancement

Harden API requests against man-in-the-middle attacks

Reported by: iandunn Owned by:
Milestone: Awaiting Review Priority: low
Severity: minor Version: 3.7.1
Component: Security Keywords:
Focuses: Cc:

Description

API requests are allowed over standard HTTP if SSL is not correctly configured on the server. That allows those servers to continue updating, rather than being stuck on an old (and potentially insecure) version (r25956).

Right now the downgrade triggers a PHP error, but users/devs will only know about it if they check the raw log files, since WP_DEBUG_DISPLAY is (hopefully) disabled on production servers. So users in this situation are mostly unaware of the server configuration errors, and the risks associated with unauthenticated API requests.

While it's good to avoid trapping them on older versions, there are a few things that we could consider to improve the mitigate the negative side-effects:

  • Prompt the user to confirm they wish to continue making the request, even though it won't be secure. This would probably need to be paired with a page on the Codex explaining the problem, and giving them a message they can copy/paste to send to their hosting provider. Normally we would avoid burdening the user with technical details like this, but this instance might be worth an exception, given the security concerns? Maybe instead of linking to the Codex, we could build a user-friendly debugging/health-status page in Core?
  • Any other ideas?

Change History (2)

#1 @jdgrimes
3 months ago

#39309 would also mitigate this as it relates to actually installing the updates, because only packages with valid signatures would be installed. So a man in the middle could not modify the package (or signature, since they need the private key to generate a valid signature).

It would not solve the problem of MitM for API requests in general though; a MitM could still prevent a site from updating by tricking it into thinking no update was available, for example.

However, a similar technique could be used, by signing all API responses.

#2 @dakami
3 months ago

(A bug finder asked me to comment.)

Insecure updates are a fairly settled matter at this point. The network is not allowed to achieve arbitrary code execution. I'm not aware of any mildly popular operating system or programming language that neither signs its packages nor operates over HTTPS, sometimes both.

Wordpress is more popular than most OS's and languages. (Congratulations, I use it myself.)

Package signing is a fairly significant undertaking, and it's my understanding there is also content from http://api.wordpress.com that gets rendered in an administrative context thus allowing takeover. This is the common class of bugs you see here -- nailing down _everything_ that needs to get signed and authenticated is difficult.

"Just use HTTPS" is a completely reasonable path. Perfect, good, etc.

The goalposts here have indeed moved; in 2018, sites not using HTTPS are being outright declared insecure by Chrome. Google's not wrong.

I'm sympathetic to the concern that there are servers with broken TLS stacks. At this point, the universality of secure updates should reduce that risk to tolerable levels. But you should be able to measure it at the https://api.wordpress.com endpoint -- look for TLS sessions that do not transition into exchanging data. I can provide Wireshark scripts to do this if it would be helpful. It is also feasible to press into service other stacks that should be ambiently available if PHP/libcurl is malfunctioning. Python comes to mind as a common coinstall due to its status as OS dependency, and at the extreme there are pure Python TLS stacks you could stub in.

Realistically though, I think you'll find from https://api.wordpress.com data that the breakage rate is pretty low, just because the same dependencies you have for TLS are shared by other codebases that must work. And if things are that broken, it probably is the sort of thing you should ask an administrator to fix.

Note: See TracTickets for help on using tickets.