Opened 10 years ago
Last modified 18 months ago
#28625 assigned enhancement
Enhancement: Add constants to support SSL connections for mysqli
Reported by: | hypertextranch | Owned by: | |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | 4.0 |
Component: | Database | Keywords: | has-patch needs-unit-tests |
Focuses: | privacy | Cc: |
Description
In order to support SSL'ed MySQL connections with the mysqli_*
functions introduced in WordPress 3.9 / PHP 5.5 mysqli_ssl_set()
must be called to set the path to the SSL certs and keys to be used by the MySQL client before mysqli_real_connect()
is called.
We should add the following optional constants to allow for users to configure secure connections to the database.
MYSQL_SSL_KEY
MYSQL_SSL_CERT
MYSQL_SSL_CA
MYSQL_SSL_CA_PATH
MYSQL_SSL_CIPHER
In addition this should only be set if the feature flag MYSQLI_CLIENT_SSL
is set for the existing MYSQL_CLIENT_FLAGS
constant.
Attachments (5)
Change History (30)
#1
@
10 years ago
- Keywords has-patch added
- Summary changed from Enhancement: Add constants for support SSL connections for mysqli to Enhancement: Add constants to support SSL connections for mysqli
#2
@
10 years ago
I agree this should be included. But, the patch shouldn't silently drop the certificate file if the file does not exist. This would allow the connection to be opened without SSL; assuming the MySQL server allows that.
It would be better to pass the parameter as given, and allow the mysqli_real_connect call to fail. This seems to be the intended idea, as the PHP docs for mysqli_ssl_set indicate it always returns TRUE (http://www.php.net/manual/en/mysqli.ssl-set.php).
#3
@
10 years ago
Your proposed method works for me. But just for good measure I think we should add a comment in the if ( $call_set )
block, maybe something along the lines of...
// SSL added here! :-)
#7
@
10 years ago
Keep in mind that solution based on constants will force SSL for every new connection so there could be problem when creating new wpdb for database which doesn't support SSL. I think SSL should be set per wpdb object.
#8
@
9 years ago
@pento, any thoughts on this?
How do other software projects handle configuration for this? I presume they do not use constants, and thus can use an array (in the case of PHP projects).
Replying to szaqal21:
Keep in mind that solution based on constants will force SSL for every new connection so there could be problem when creating new wpdb for database which doesn't support SSL. I think SSL should be set per wpdb object.
I agree with the concern here.
#9
follow-up:
↓ 10
@
9 years ago
- Keywords needs-refresh needs-unit-tests added; dev-feedback 4.1-early removed
- Milestone changed from Future Release to 4.5
Other projects generally use PDO, and do their DB config as arrays, instead of constants.
mysqli_ssl_set()
was added in PHP 5.3 - we probably should add a function_exists()
check, even though it'd really only be a problem if someone has defined WP_USE_EXT_MYSQL
as false
in PHP 5.2. (And maybe fail to connect in this case, so that we're not silently using a non-SSL connection.)
For the concern about new wpdb instances, perhaps we need to add an $options
parameter to wpdb::__construct()
? $options['ssl']
would be an array of the SSL options (if your global config doesn't do SSL, or you want different SSL options), or false
to prevent an SSL connection. Undefined uses the global config.
For the actual patch itself, I'm not wild about adding a pile of constants, but that's kind of the best option that keeps with the WordPress-y way. I can't decide if the foreach
/ call_user_func_array
combination is too clever, or just the right amount of clever. It'd need to be reworked to work with $options
, anyway. Also, it needs unit tests.
With all that said, I find myself being in favour of adding this functionality to Core, instead of recommending a drop-in. It's useful, it increases security, and I don't think it's possible to render your site unrecoverably broken (worst case: remove the constants from wp-config.php
) with it.
#10
in reply to:
↑ 9
@
9 years ago
Replying to pento:
With all that said, I find myself being in favour of adding this functionality to Core, instead of recommending a drop-in. It's useful, it increases security, and I don't think it's possible to render your site unrecoverably broken (worst case: remove the constants from
wp-config.php
) with it.
100% agree with the final sentence. In this day and age there is no excuse not to use secure communications. Hope this does make it to Core.
This ticket was mentioned in Slack in #core by jorbin. View the logs.
9 years ago
#14
@
8 years ago
I agree with most of what pento suggests as well but in the meantime I have published the plugin I've been using to set SSL flags for connections as a stop gap.
This ticket was mentioned in Slack in #forums by danhgilmore. View the logs.
7 years ago
#18
@
4 years ago
Just wondering what is necessary to jump-start the effort on this ticket moving again (hopefully, for 5.8)?
I have a new project where I require secure DB connections. I've tests @hypertextranch 's plugin and it seems that it will work for us. However, since it uses a custom db.php
drop-in, would be really nice to have this in core as there are many other highly used plugins (e.g., W3TC and QM) that need/want their own drop-ins.
#21
follow-up:
↓ 22
@
4 years ago
Note, I discovered over the weekend that, in at least some cases, WP 5.6 is capable of opening a secure connection to MySQL without any mods (or need for something like the Secure DB Connection plugin).
Don't know whether that is a result of changes in core/MySQL/PHP since this ticket was opened (until a few days ago I didn't know that encrypted connections to MySQL where possible :-)
I've tested in the follow 2 environments, and all I had to do was add
define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL )
to wp-config.php
to get an encrypted connection.
Windows
WP 5.6
PHP 7.4.13
MySQL 5.7.10
Apache 2.4.37
CentOS 7
WP 5.6
PHP 7.4.14
MySQL 5.7.33
Apache 2.4.6 (altho I believe this includes many patches after that offial version num)
That doesn't mean that this ticket can be closed however. I guess there are setups that would require specifying other than default certs, which the patch allows to happen.
p.s. threw together a little plugin that displays whether the connection is secure:
- At a Glance (and Network Right Now) dashboard widget (like Secure DB Connection does)
- an admin bar node
- a Site Health test and debug_info (the text of those need more work)
You can grab it from it from GitHub
#22
in reply to:
↑ 21
;
follow-up:
↓ 24
@
4 years ago
Replying to pbiron:
Note, I discovered over the weekend that, in at least some cases, WP 5.6 is capable of opening a secure connection to MySQL without any mods (or need for something like the Secure DB Connection plugin).
Don't know whether that is a result of changes in core/MySQL/PHP since this ticket was opened (until a few days ago I didn't know that encrypted connections to MySQL where possible :-)
I've tested in the follow 2 environments, and all I had to do was add
define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL )
to
wp-config.php
to get an encrypted connection.
I believe it depends on your server setup, if the system MySQL client was installed with trusted root certs and your database is using a key/cert that's signed by a root cert that you trust on the client then just adding the MYSQLI_CLIENT_SSL
flag is enough. On modern systems with more root CAs preinstalled and use of cloud based database services that configure and install keys signed by common root CAs the need to explicitly set custom keys/certs/CAs becomes less needed.
This issue / patch was made for a time when things like https://letsencrypt.org didn't exist and spinning up a database didn't always come with a cert and might mean needing to generate random self-signed stuff.
#23
@
4 years ago
SSL shouldn't be set by constants inside db_connect(), it will force SSL for every new wpdb() even for custom (external connections) to databases without SSL support. SSL should be set by passing some extra args to new wpdb() or some kind of filter before connection is made.
Attaching my db.php dropin.
#24
in reply to:
↑ 22
@
18 months ago
Replying to hypertextranch:
I believe it depends on your server setup, if the system MySQL client was installed with trusted root certs and your database is using a key/cert that's signed by a root cert that you trust on the client then just adding the
MYSQLI_CLIENT_SSL
flag is enough. On modern systems with more root CAs preinstalled and use of cloud based database services that configure and install keys signed by common root CAs the need to explicitly set custom keys/certs/CAs becomes less needed.
This issue / patch was made for a time when things like https://letsencrypt.org didn't exist and spinning up a database didn't always come with a cert and might mean needing to generate random self-signed stuff.
Actually this patch is more pertinent now than you might think.
Specifically, being able to specify a key/cert/ca at the client side allows the server to reject connections with untrusted certificates. Some of the cloud hosting environments require a client side key/cert to be used.
Would very much like to see this rolled into core.
#25
@
18 months ago
Just as a heads up for anyone else using the secure db connection plugin, you need to tweak db.php to disable mysqli error reporting as wordpress handles this itself.
Without this, installation of a clean site will fail with a blank screen and errors in the logs.
Around line 39 of db.php, right after:
if ( $this->use_mysqli ) {
Add the line:
mysqli_report( MYSQLI_REPORT_OFF );
The resultant code will look like:
if ( $this->use_mysqli ) {
mysqli_report( MYSQLI_REPORT_OFF );
$this->dbh = mysqli_init();
Initial proposed patch