Pings/Trackbacks: Disable pings in non-production environments#11476
Pings/Trackbacks: Disable pings in non-production environments#11476arcangelini wants to merge 6 commits intoWordPress:trunkfrom
Conversation
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
16bf231 to
efa3dfb
Compare
The global pings_open filter suppressed the X-Pingback header which wp_install_maybe_enable_pretty_permalinks() uses to verify rewrite rules, breaking pretty permalinks on fresh non-production installs. Use pre_trackback_post action to reject incoming trackbacks instead, which only affects the wp-trackback.php entry point. Reverts the pingsOpen and sendHeaders test changes since pings_open is no longer filtered.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
ramonjd
left a comment
There was a problem hiding this comment.
Thanks for the PR!
Things are working as expected in my testing. It'd be good to get a second eye on this to confirm.
cc @cagrimmett
I tested by switching my config from define( 'WP_ENVIRONMENT_TYPE', 'local' ); to define( 'WP_ENVIRONMENT_TYPE', 'production' ); and back again.
Verified the method was returning what we expect:
wp eval "var_dump( wp_should_disable_pings_for_environment() );" // => bool(true)wp eval "define('WP_ENVIRONMENT_TYPE','production'); var_dump( wp_should_disable_pings_for_environment() );" // => bool(false)Verify outgoing pings are suppressed
wp eval "do_action('do_all_pings'); var_dump( has_action('do_all_pings','do_all_pingbacks') );"production: int(10)
local: bool(false)
Verify incoming XML-RPC pingback is removed
wp eval "
\$result = wp_disable_xmlrpc_pingback_for_environment( array(
'pingback.ping' => 'test',
'wp.getPost' => 'test',
) );
var_dump( \$result );production:
array(2) {
["pingback.ping"]=>
string(4) "test"
["wp.getPost"]=>
string(4) "test"
}local:
array(1) {
["wp.getPost"]=>
string(4) "test"
}And with the filter
wp eval "
\$methods = apply_filters( 'xmlrpc_methods', array(
'pingback.ping' => 'test',
'wp.getPost' => 'test',
) );
var_dump( array_keys( \$methods ) );" production:
array(2) {
[0]=>
string(13) "pingback.ping"
[1]=>
string(10) "wp.getPost"
}local:
array(1) {
[0]=>
string(10) "wp.getPost"
}Override filter is working
wp eval "add_filter('wp_should_disable_pings_for_environment','__return_false');
var_dump( wp_should_disable_pings_for_environment() );" // => bool(false)
tyxla
left a comment
There was a problem hiding this comment.
This appears to be working well in my testing. 👍
I do have some precision and accuracy suggestions, as well as some edge case handling to be considered.
src/wp-includes/default-filters.php
Outdated
| add_action( 'do_all_pings', 'generic_ping', 10, 0 ); | ||
|
|
||
| // Disable pings (pingbacks, trackbacks, and ping service notifications) in non-production environments. | ||
| add_action( 'do_all_pings', 'wp_disable_outgoing_pings_for_environment', 1, 0 ); |
There was a problem hiding this comment.
Worth checking if there are any major plugins tinkering with this filter, and re-adding these callbacks before/at the default priority of 10. We can use https://wpdirectory.net/ to be sure.
There was a problem hiding this comment.
Worth checking if there are any major plugins tinkering with this filter
Ran the wpdirectory search for ['"]do_all_pings['"] and went through all 22 hits. Most are references (JSON exclude lists, hook dumps, doc snippets) while the rest are removing this action from the do_pings hook. Seems like we are safe?
| */ | ||
| function wp_disable_xmlrpc_pingback_for_environment( $methods ) { | ||
| if ( wp_should_disable_pings_for_environment() ) { | ||
| unset( $methods['pingback.ping'] ); |
There was a problem hiding this comment.
Are we intentionally leaving the readonly pingback.extensions.getPingbacks() intact for non-production environments?
There was a problem hiding this comment.
Honestly it was a bit of an oversight initially, but thinking about it more I'm leaning toward leaving it alone. It's a read-only SELECT against the comments table, so it feels like it sits outside what this PR is really targeting (staging pinging prod, or accepting incoming pings).
The other thing that stopped me was that existing pingbacks are still visible in the admin, REST API, get_comments(), etc. on non-prod. Stripping just this one read method while leaving all those alone felt inconsistent. I am open on this though.
There was a problem hiding this comment.
Yeah, maybe we should leave it alone. Maybe the site owner disabled pingbacks after having them enabled for a while before.
Trac Ticket
https://core.trac.wordpress.org/ticket/64837
Summary
When
WP_ENVIRONMENT_TYPEislocal,development, orstaging, pingbacks and trackbacks are sent when posts are published. This creates confusion on the receiving end and is unnecessary for testing workflows.This PR disables all outgoing and incoming pings in non-production environments by default:
do_all_pingbacks,do_all_trackbacks, andgeneric_pingcallbacks from thedo_all_pingsaction (at priority 1, before they fire at priority 10). Enclosures (do_all_enclosures) are intentionally left untouched.xmlrpc_methodsto removepingback.ping.pre_trackback_postto reject trackbacks before they are processed.Note:
pings_open()is intentionally not filtered, because it would suppress theX-Pingbackheader thatwp_install_maybe_enable_pretty_permalinks()relies on to verify rewrite rules during fresh installs.Override filter
Developers can re-enable pings in non-production environments:
Or disable pings even in production:
Test instructions
WP_ENVIRONMENT_TYPEtolocal,development, orstagingWP_ENVIRONMENT_TYPEtoproductionand verify pings work normallynpm run test:php -- --filter Tests_Comment_DisablePingsForEnvironmentFiles changed
src/wp-includes/comment.php— Four new functions:wp_should_disable_pings_for_environment()(public API with filter),wp_disable_outgoing_pings_for_environment(),wp_disable_trackback_for_environment(),wp_disable_xmlrpc_pingback_for_environment()src/wp-includes/default-filters.php— Register the three hook callbackstests/phpunit/tests/comment/disablePingsForEnvironment.php— 17 new tests covering all environment types, filter overrides, and edge cases