Conversation
… into plugin-checksums
…d not be retrieved.
Multiple checksums act as a whitelist, accepting any one of the available checksums as proof for the file's integrity. Fixes #24
src/Checksum_Base_Command.php
Outdated
| /** | ||
| * Recursively get the list of files for a given path. | ||
| * | ||
| * @param string $path Root parse to start the recursive traversal in. |
| Scenario: Multiple checksums for a single file are supported | ||
| Given a WP install | ||
|
|
||
| When I run `wp plugin install wptouch --version=4.3.22` |
There was a problem hiding this comment.
Could you add a comment here that wptouch has sha256 (and md5) checksums with multiple values per file as it's not immediately obvious what's being tested here...
There was a problem hiding this comment.
I thought the scenario name Multiple checksums for a single file are supported already gave that away...?
There was a problem hiding this comment.
Ha yeah it does, it just wasn't obvious to me why wptouch should test it... ignore at will!
There was a problem hiding this comment.
Oh, I see. The choice of the plugin was based on the issue that reported the error: #24
I might add comments to link the tests to the relevant source issues then.
| $plugins = $fetcher->get_many( $all ? $this->get_all_plugin_names() : $args ); | ||
|
|
||
| if ( empty( $plugins ) && ! $all ) { | ||
| WP_CLI::error( 'You need to specify either one or more plugin slugs to check or use the --all flag to check all plugins.' ); |
There was a problem hiding this comment.
Could you add a test to provoke this error (and similarly for other errors/warnings - where feasible!)?
src/Checksum_Plugin_Command.php
Outdated
|
|
||
| if ( empty( $this->errors ) ) { | ||
| WP_CLI::success( | ||
| count( $plugins ) > 1 |
There was a problem hiding this comment.
At the moment if you do wp checksum plugin hello then you get a warning about checksums not being available and Success: Plugin verifies against checksums. at the end. It'd probably be better to use Utils\report_batch_operation_results() instead once (after the error report if any), and also have a skip count to give it.
There was a problem hiding this comment.
If you keep a $skips count and then pass it it should work ok eg:
if ( ! empty( $this->errors ) ) {
$formatter = new \WP_CLI\Formatter(
$assoc_args,
array( 'plugin_name', 'file', 'message' )
);
$formatter->display_items( $this->errors );
}
$total = count( $plugins );
$failures = count( $this->errors );
$successes = $total - $failures - $skips;
Utils\report_batch_operation_results( 'plugin', 'verify', $total, $successes, $failures, $skips );
| */ | ||
| private function get_all_plugin_names() { | ||
| $names = array(); | ||
| foreach ( get_plugins() as $file => $details ) { |
There was a problem hiding this comment.
I'm wondering if the all_plugins filter should be applied here or not??
There was a problem hiding this comment.
I think that would introduce a security vulnerability, as a malicious plugin could just filter itself out of the integrity check.
src/Checksum_Plugin_Command.php
Outdated
| * @return array<string> Array of files with their relative paths. | ||
| */ | ||
| private function get_plugin_files( $path ) { | ||
| // TODO: Make sure this works for all types of plugins (single files, must-use, ...) |
There was a problem hiding this comment.
I think for future proofing it should check here that $path includes a directory and isn't just a bare file like hello.php.
There was a problem hiding this comment.
Ah, yes, thanks for catching the TODO, that does indeed still need an implementation.
There was a problem hiding this comment.
So, I just checked, and the current code just works with bare files like hello.php as well. I don't think that we want to force the need for a folder for plugins.
However, must-use plugins are currently being ignored...
There was a problem hiding this comment.
But $folder = trailingslashit( dirname( $this->get_absolute_path( $path ) ) ); where $path === "hello.php" will just cause the plugins directory to be traversed. I was thinking of it doing something like:
if ( false === strpos( $path, '/' ) ) {
return array( $this->get_absolute_path( $path ) );
}
However, must-use plugins are currently being ignored...
I was wondering if they're ever stored on wordpress.org/plugins, and would checksums ever be provided?
There was a problem hiding this comment.
Re. single file. Yes, you are right. I did some deeper checking, and it only worked right now because the checksum could not be retrieved for hello.php (as the hello-dolly plugin is different on the repository).
Re. must-use plugins, I know that some people just move existing plugins into the must-use folder for client sites, to make sure they can't be disabled. This is usually done by adding something like the bedrock mu-plugins autoloader.
There was a problem hiding this comment.
I have fixed the single file issue (commits incoming). I suggest skipping the mu-checking for now and adding a separate issue for that, it might need more discussion.
src/Checksum_Base_Command.php
Outdated
| foreach ( $files as $file_info ) { | ||
| $pathname = substr( $file_info->getPathname(), strlen( $path ) ); | ||
| if ( $file_info->isFile() && $this->filter_file( $pathname ) ) { | ||
| $filtered_files[] = str_replace( $path, '', $file_info->getPathname() ); |
There was a problem hiding this comment.
Could you reuse $pathname here (also technically more correct!)...
There was a problem hiding this comment.
I originally built it this way to have wp-content/plugins be the root and everything else related to that.
This means that you have the plugin's folder included in the file name for error messages, like akismet/akismet.php.
This serves two purposes:
- Allow proper delineation between plugins in a folder, and single-file plugins that don't have their own folder.
- Show whatever custom folder name the plugin happens to be installed in. Potentially, you can even have the same plugin installed in multiple versions, with differing checksum errors. Showing the folder helps you identify which one is being checked.
Can you elaborate why you think your suggestion is "technically more correct" ?
There was a problem hiding this comment.
I just meant to do $filtered_files[] = $pathname rather than the str_replace() - it's a pet bugbear of mine when I see this str_replace() pattern used on paths when it should be the "correct" substr() - as used here for $pathanme - but totally ignorable...
There was a problem hiding this comment.
I guess I can replace the str_replace() with a substr() anyway...
There was a problem hiding this comment.
Oh, nvm, I just noticed it myself... Doing the change now! :)
|
Good stuff. We have our first headline release feature! |
|
Hey guys, really love this feature. I didn't see it explicitly mentioned in any of the changes for 1.5. Will this be included in WP CLI 1.5? |
|
Absolutely! |
|
@nateinaction Yes, it will be part of 1.5, coming soon! |
|
Thanks again guys! |
|
@schlessera was wondering should a release be made of |
Add plugin checksums verification

Initial implementation of the plugin checksum verification.
The WordPress.org infrastructure now calculates MD5 and SHA-256 checksums for all plugin files and stores them in a publically accessible way. You can find a specification of the current endpoint to retrieve the checksums here.
The
wp checksum plugincommand goes through some or all of the plugins installed on a machine, downloads the checksums for each plugin, and then verifies the downloaded checksums against freshly generated ones.Uses https://meta.trac.wordpress.org/ticket/3192
Resolves #15