WordPress.org

Make WordPress Core

Opened 7 months ago

Closed 4 months ago

Last modified 4 months ago

#45806 closed defect (bug) (fixed)

Add sodium_compat -- a libsodium-compatible cryptography API for PHP <7.2

Reported by: paragoninitiativeenterprises Owned by: tellyworth
Milestone: 5.2 Priority: normal
Severity: normal Version: 5.1
Component: General Keywords: has-patch
Focuses: Cc:

Description

Related to the work in #39309, but also related to the push to PHP 7+ (as mentioned by Jenny Wong on Twitter)...

Sodium is a modern, easy-to-use software library for encryption, decryption, signatures, password hashing and more.

It is a portable, cross-compilable, installable, packageable fork of NaCl, with a compatible API, and an extended API to improve usability even further.

Its goal is to provide all of the core operations needed to build higher-level cryptographic tools.

The Sodium cryptography library was integrated with the PHP core in PHP 7.2 after a unanimous 37-0 vote in favor. It's the recommended cryptography library for most modern software developers.


Sodium_Compat is a pure-PHP implementation of most of libsodium, that has been in development for over two years (first commit: Nov 24, 2016) and has a stable API.

Sodium_Compat functions on both 32-bit and 64-bit systems, Linux and non-Linux, and was engineered at every level to resist side-channel attacks. You can learn more about these design considerations here.

Caveat: If PHP_INT_SIZE === 4 its public-key cryptography implementations are much slower than PHP_INT_SIZE === 8, but there's no safe way to get around this limitation.

You can detect this at runtime with ParagonIE_Sodium_Compat::polyfill_is_fast(). This will return TRUE if the libsodium extension is installed OR PHP_INT_SIZE === 8. It will return FALSE otherwise.

The pwhash API was not polyfilled, because it is not possible to efficiently implement scrypt or Argon2 in pure-PHP.


By adding sodium_compat to WordPress in the next major release (5.1 or 5.2), you can guarantee that plugin developers have immediate access to the polyfilled features. This should make it easier to push for PHP 7.2 as a minimum supported version in the year 2020, as it enables plugins to be written for PHP 7 now without breaking old systems.

It also makes the code diff for #39309 much smaller.

The patch adds sodium_compat v1.8.0 to WordPress, but unlike the patches in #39309, doesn't do anything further. Our patch emphatically does not touch the auto-updater code at all, so there is no risk of breakage.

Attachments (1)

WordPress_sodium_compat.patch (1.1 MB) - added by paragoninitiativeenterprises 7 months ago.
sodium_compat v1.8.0 for WordPress

Download all attachments as: .zip

Change History (11)

@paragoninitiativeenterprises
7 months ago

sodium_compat v1.8.0 for WordPress

This ticket was mentioned in Slack in #core by paragonie. View the logs.


7 months ago

This ticket was mentioned in Slack in #core-restapi by greatislander. View the logs.


7 months ago

#3 @ayeshrajans
6 months ago

Hi Scott,
I'm not someone who has the rights to make a decision on this, but as someone who uses WordPress and contributes to it, I would like to put my 2 cents.

I can't express this enough on how much I appreciate you making modern security libraries accessible to lesser fortunate PHP systems that cannot use libsodium extension. In a CMS Unconference event, I was talking with a few security team members in Joomla about including sodium_compat in core. Joomla is in a rapid path to drop backwards compatibility in favor of adopting modern cryptography. Joomla already has crypt component, and the inclusion agrees with them well.

Maintenance overhead

Every dependency we _ship_ with WordPress increases the maintenance overhead. I just opened a ticket to upgrade the PHPMailer library. WordPress does not utilize cryptogrphic functions to the extent of Joomla, and from both consumer and a WorPress developer perspective, I personally do not think including a library of this size (1MB patch) and security-importance is justifiable.

Dependencies

With the support for PHP 5.2 dropped, there is more incentive to use Composer. Many WordPress sites already use Composer (although there is no support in core), and they can already _require_ sodium_compat if they have a need to do so.

With the sodium_compat library in core, we are shipping one more dependency to _everyone_, without a use for it right away, and with only plans to do in the future.

libsodium suitability

One of the biggest motivations to use libsodium is in how dangerous the defaults of OpenSSL can be, and the adoption of new EC curves and ciphers. This does not mean OpenSSL is downright broken. If you use the right options, and make sure to authenticate everything, OpenSSL can still provide usable. Composer itself uses OpenSSL, and recent PHP package validation projects such such as Phive use pgp for package signing.

OpenSSL or GPG, they use the same well tested and reviewed binaries. It does not matter how they are linked, but they use the same code nonetheless. Sodium_compat is however, a compat library. I think the first question if whether we should use libsodium before jumping into a the next step of providing compatibility for those who don't have libsodium (i.e including sodium_compat).

sodium_compat suitability

Even if libsodium has received enough scrutiny, this does not mean sodium_compat had the same amount of review done on its code.

https://github.com/paragonie/sodium_compat/graphs/contributors

Looking at the real humans involved in this library, it only had 9 non-Paragon contributors. All commits from these contributors are trivial changes such as typo fixes and small bug fixes.

I see the Paragon IE is a commercial organization providing support commercial support for this library. While I'm not sure how many people are involved under paragonie-security Github handle, I can't help but notice the how much this library is attached to ParagonIE. In my opinion, this is not a good flag, because in case ParagonIE loses interest in maintaining sodium_compat, there are not enough people who are involved to fork and maintain this project. While WordPress includes libraries written by a single author, that is because historical reasons and in how small a certain library.

In addition, sodium_compat has _not_ received a proper security review. While I'm aware of you requesting support support from WordPress Association, I still think it's premature to include a library of this stage in WordPress.

--

Once again I should highlight that I, and I'm sure everyone in WordPress ecosystem too, appreciate your work and good intentions all your work on this. It's not my decision at all, and while I have faith in those who make the decision to do the best for WordPress, I doubt they would decide to go with sodium_compat, at least in current stage.

#4 @paragoninitiativeenterprises
6 months ago

Hi @ayeshrajans,

I think the first question if whether we should use libsodium before jumping into a the next step of providing compatibility for those who don't have libsodium (i.e including sodium_compat).

That is a reasonable conversation to have, although I suspect the answer will be informed by the PHP community's adoption of libsodium as the preferred cryptography library in PHP 7.2+. It's already provided in Joomla and Magento.

In addition, sodium_compat has _not_ received a proper security review. While I'm aware of you requesting support support from WordPress Association, I still think it's premature to include a library of this stage in WordPress.

This concern has been addressed here: https://core.trac.wordpress.org/ticket/39309#comment:41

To summarize:

  • It's true that we have not forked over the probably hundreds of thousands of dollars necessary for a thorough third-party audit of this library against side-channels on every relevant version of PHP. Such an audit would depend largely on the behavior of the PHP interpreter at various stages in its evolution, so this is unavoidable.
  • It would be disingenuous to say that it has not received any security review, however. The security teams of Joomla and Magento both reviewed it and decided that it was suitable enough to provide encryption in their platforms. Neither Michael Babker nor Piotr Kaminsky are known to jump the shark on radical changes that they have to live with for years.

I'd like to add two further points:

  • Who, exactly, is qualified to perform the necessary security review? And of those rare few that have the background necessary to provide a careful review, would any of them even be available for months to do so? (As the vendor for sodium_compat, we're immediately disqualified from this position, since first-party audits are meaningless when establishing trust.)
  • Which other libraries and components used by WordPress are held to the same standard being proposed here? You mentioned PHPMailer, but I don't recall any version of it being subjected to a third-party code audit before being accepted into the WordPress core.

If the opinion of the WordPress.org team is "sodium_compat must be audited before it can be included", then they should have no trouble getting their member companies (Automattic, et al.) to pay a third-party to conduct such an audit to serve the community's best interest.

Otherwise, this is a needless and excessive burden that doesn't serve the community's best interests. It would be reduced to a mere double standard that promotes bad habits.

With the sodium_compat library in core, we are shipping one more dependency to _everyone_, without a use for it right away, and with only plans to do in the future.

The inclusion of sodium_compat provides at least an immediate benefit and a long-term benefit (and probably many more that are difficult to predict right now).

Immediately: Plugin developers can migrate away from libmcrypt to libsodium today, even if their plugins are deployed on PHP 5.2 right now, with minimal risk of migration friction caused by system incompatibility. Which, by the way, is a lot of plugins (over 11,000) today.

Long-term: The barrier-to-entry for implementing code-signing in the automatic update process becomes much lower. The focus for that discussion can be entirely on key management and failure conditions, moving forward.

Eventually an authority-free PKI can be formalized and considered for implementation so that plugin developers can sign their own plugins with their own, privately-held Ed25519 keys.

Looking at the real humans involved in this library, it only had 9 non-Paragon contributors. All commits from these contributors are trivial changes such as typo fixes and small bug fixes.

This is true, but I'm unsure of what can be done to improve this metric, or what the target number even is.

I see the Paragon IE is a commercial organization providing support commercial support for this library. While I'm not sure how many people are involved under paragonie-security Github handle, I can't help but notice the how much this library is attached to ParagonIE. In my opinion, this is not a good flag, because in case ParagonIE loses interest in maintaining sodium_compat, there are not enough people who are involved to fork and maintain this project. While WordPress includes libraries written by a single author, that is because historical reasons and in how small a certain library.

Here's the worst case scenario:

Let's say my coworkers and myself all get hit by a bus the day after WordPress releases libsodium support.

The library is published under the extremely permissive ISC license, and can be forked by anyone for any reason, without any significant licensing or copyright burdens. The PHP community could then decide to step in for Paragon and decide on an "official" fork, should one be deemed necessary.

Assuming an official fork is created, WordPress can decide whether or not to adopt the "official" fork or stick with the existing compat library until everyone is on PHP 7.2, then delete it forever.

If, as you said, there is no one able or willing to create an official fork for the PHP community, then as soon as PHP 7.2 is the minimum supported version of WordPress, none of this will matter.

But barring any catastrophic events that kills off everyone in our company, I can promise you the probability of us "losing interest in maintaining sodium_compat" is 0%.

The reason for this is simple: We're a for-profit, privately owned company and one of our revenue sources is enterprise support contracts. One of our open source libraries that we're paid to maintain (CipherSweet) has a hard dependency on sodium_compat. It would make no business sense for us to drop sodium_compat support even if we weren't already opposed to its abandonment.

And if the people reading this comment can't trust our word, you can trust our incentives, right?


I hope this adequately addresses your concerns about sodium_compat support. If WordPress moves to PHP 5.3+ and Composer support sooner, an alternative patch (one line added to composer.json instead of 1 MB of PHP scripts) is certainly worth considering instead.

However, it should be abundantly clear that the benefits of sodium_compat far outweigh the known risks, and should still significantly outweigh the perceived risks.

#5 @pento
6 months ago

  • Milestone changed from Awaiting Review to 5.2

#6 @mnelson4
5 months ago

FYI Wordfence recently added sodium_compat to their plugin (version 7.2.1), so it's in use by about half of the 2 million WordPress sites using Wordfence. See https://plugins.trac.wordpress.org/browser/wordfence/trunk/vendor/paragonie/sodium_compat

This ticket was mentioned in Slack in #core by tellyworth. View the logs.


4 months ago

#8 @tellyworth
4 months ago

  • Owner set to tellyworth
  • Resolution set to fixed
  • Status changed from new to closed

In 44953:

General: Add sodium_compat library for crypto APIs in PHP < 7.2

This adds a pure PHP implementation of the cryptographic functions supported in PHP 7.2+. It provides the necessary backwards compatibility required to support signature verification and other security features going forward across all supported PHP versions.

Props paragoninitiativeenterprises
Fixes #45806. See #39309.

#9 @tellyworth
4 months ago

In 44954:

Upgrade/Install: Add experimental package signing to some updates.

This adds code for soft verification of signatures for theme and plugin installs and updates, when provided by the update server. This experimental version does not reject unverified packages or failed signatures; it simply reports anonymous errors so we can evaluate its feasibility and detect incompatibilities.

This code relies on the new sodium_compat library for PHP versions prior to 7.2.

Props dd32, paragoninitiativeenterprises.
See #39309, #45806.

#10 @tellyworth
4 months ago

In 44955:

Coding Standards: exclude sodium_compat library.

Props dd32.
See #45806.

Note: See TracTickets for help on using tickets.