Skip to content

Commit

Permalink
Security: Introduce Grunt task for updating Root Certificates.
Browse files Browse the repository at this point in the history
The Root Certificate bundle maintained by Mozilla ships in WordPress to allow SSL certificates to be verified on hosts with incomplete, outdated, or invalid local SSL configurations. To date, updates have only been merged into Core when problems arise using a highly manual process.

This introduces the `certificates:upgrade` Grunt task to automate the process of updating the included bundle with upstream changes using Composer to manage versioning.

The legacy 1024bit certificates included for backwards compatibility are now maintained in a separate file that is prepended to the built version of the bundle during the relevant Grunt tasks. Some expired certificates from this list have been removed:

- Cybertrust Global Root (expired 2021-12-15)
- Thawte Server CA (expired 2020-12-31)
- Thawte Premium Server CA (expired 2020-12-31)

The Dependabot configuration has also been updated to open pull requests when new releases occur upstream. Going forward, the recommendation is to create a task ticket for updating these certificates with each release when an update is published. See #62811 for an example of this.

Props johnbillion, desrosj, whyisjake, ayeshrajans, SergeyBiryukov, swissspidy, skithund, barry.
Fixes #62812. See #62811, 50828.

git-svn-id: https://develop.svn.wordpress.org/trunk@59740 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
desrosj committed Jan 30, 2025
1 parent 439b172 commit 6db1a33
Show file tree
Hide file tree
Showing 6 changed files with 4,977 additions and 1,192 deletions.
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,20 @@ updates:
github-actions:
patterns:
- "*"

# Check for updates to Composer packages.
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
ignore:
# These dependencies do not currently need to be managed with Dependabot.
- dependency-name: "squizlabs/php_codesniffer"
- dependency-name: "wp-coding-standards/wpcs"
- dependency-name: "phpcompatibility/php-compatibility"
- dependency-name: "yoast/phpunit-polyfills"
groups:
composer-packages:
patterns:
- "composer/ca-bundle"
46 changes: 46 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ module.exports = function(grunt) {
src: buildFiles.concat( [
'!wp-includes/assets/**', // Assets is extracted into separate copy tasks.
'!js/**', // JavaScript is extracted into separate copy tasks.
'!wp-includes/certificates/cacert.pem*', // Exclude raw root certificate files that are combined into ca-bundle.crt.
'!wp-includes/certificates/legacy-1024bit.pem',
'!.{svn,git}', // Exclude version control folders.
'!wp-includes/version.php', // Exclude version.php.
'!**/*.map', // The build doesn't need .map files.
Expand Down Expand Up @@ -478,6 +480,10 @@ module.exports = function(grunt) {
},
src: '.github/workflows/*.yml',
dest: './'
},
certificates: {
src: 'vendor/composer/ca-bundle/res/cacert.pem',
dest: SOURCE_DIR + 'wp-includes/certificates/cacert.pem'
}
},
sass: {
Expand Down Expand Up @@ -859,6 +865,16 @@ module.exports = function(grunt) {
WORKING_DIR + 'wp-includes/js/wp-emoji.min.js'
],
dest: WORKING_DIR + 'wp-includes/js/wp-emoji-release.min.js'
},
certificates: {
options: {
separator: '\n\n'
},
src: [
SOURCE_DIR + 'wp-includes/certificates/legacy-1024bit.pem',
SOURCE_DIR + 'wp-includes/certificates/cacert.pem'
],
dest: SOURCE_DIR + 'wp-includes/certificates/ca-bundle.crt'
}
},
patch:{
Expand Down Expand Up @@ -1528,6 +1544,34 @@ module.exports = function(grunt) {
'usebanner'
] );

grunt.registerTask( 'certificates:update', 'Updates the Composer package responsible for root certificate updates.', function() {
var done = this.async();
var flags = this.flags;
var args = [ 'update' ];

grunt.util.spawn( {
cmd: 'composer',
args: args,
opts: { stdio: 'inherit' }
}, function( error ) {
if ( flags.error && error ) {
done( false );
} else {
done( true );
}
} );
} );

grunt.registerTask( 'build:certificates', [
'concat:certificates'
] );

grunt.registerTask( 'certificates:upgrade', [
'certificates:update',
'copy:certificates',
'build:certificates'
] );

grunt.registerTask( 'build:files', [
'clean:files',
'copy:files',
Expand Down Expand Up @@ -1655,9 +1699,11 @@ module.exports = function(grunt) {
grunt.task.run( [
'build:js',
'build:css',
'build:certificates'
] );
} else {
grunt.task.run( [
'build:certificates',
'build:files',
'build:js',
'build:css',
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"ext-dom": "*"
},
"require-dev": {
"composer/ca-bundle": "1.5.5",
"squizlabs/php_codesniffer": "3.10.3",
"wp-coding-standards/wpcs": "~3.1.0",
"phpcompatibility/phpcompatibility-wp": "~2.1.3",
Expand Down
Loading

0 comments on commit 6db1a33

Please sign in to comment.