* $wp_xmlrpc_server->message looks like this:
[messageType] => methodCall
[methodName] => pingback.ping
[0] => http://www.example.net/?p=1 // Site that created the pingback.
[1] => https://www.example.com/?p=2 // Post being pingback'd on this site.
$pingback_args = $wp_xmlrpc_server->message->params;
if ( ! empty( $pingback_args[1] ) ) {
$post_id = url_to_postid( $pingback_args[1] );
// If pingbacks aren't open on this post, we'll still check whether this request is part of a potential DDOS,
// but indicate to the server that pingbacks are indeed closed so we don't include this request in the user's stats,
// since the user has already done their part by disabling pingbacks.
$pingbacks_closed = false;
$post = get_post( $post_id );
if ( ! $post || ! pings_open( $post ) ) {
$pingbacks_closed = true;
// Note: If is_multicall is true and multicall_count=0, then we know this is at least the 2nd pingback we've processed in this multicall.
'comment_author_url' => $pingback_args[0],
'comment_post_ID' => $post_id,
'comment_author_email' => '',
'comment_type' => 'pingback',
'akismet_pre_check' => '1',
'comment_pingback_target' => $pingback_args[1],
'pingbacks_closed' => $pingbacks_closed ? '1' : '0',
'is_multicall' => $is_multicall,
'multicall_count' => $multicall_count,
$comment = Akismet::auto_check_comment( $comment );
is_wp_error( $comment ) // This triggered a 'discard' directive.
|| ( isset( $comment['akismet_result'] ) && 'true' == $comment['akismet_result'] ) // It was just a normal spam response.
// Sad: tightly coupled with the IXR classes. Unfortunately the action provides no context and no way to return anything.
$wp_xmlrpc_server->error( new IXR_Error( 0, 'Invalid discovery target' ) );
// Also note that if this was part of a multicall, a spam result will prevent the subsequent calls from being executed.
// This is probably fine, but it raises the bar for what should be acceptable as a false positive.
* Ensure that we are loading expected scalar values from akismet_as_submitted commentmeta.
* @param mixed $meta_value
private static function sanitize_comment_as_submitted( $meta_value ) {
if ( empty( $meta_value ) ) {
$meta_value = (array) $meta_value;
foreach ( $meta_value as $key => $value ) {
if ( ! is_scalar( $value ) ) {
unset( $meta_value[ $key ] );
// These can change, so they're not explicitly listed in comment_as_submitted_allowed_keys.
if ( strpos( $key, 'POST_ak_' ) === 0 ) {
if ( ! isset( self::$comment_as_submitted_allowed_keys[ $key ] ) ) {
unset( $meta_value[ $key ] );
public static function predefined_api_key() {
if ( defined( 'WPCOM_API_KEY' ) ) {
return apply_filters( 'akismet_predefined_api_key', false );
* Controls the display of a privacy related notice underneath the comment form using the `akismet_comment_form_privacy_notice` option and filter respectively.
* Default is top not display the notice, leaving the choice to site admins, or integrators.
public static function display_comment_form_privacy_notice() {
if ( 'display' !== apply_filters( 'akismet_comment_form_privacy_notice', get_option( 'akismet_comment_form_privacy_notice', 'hide' ) ) ) {
'akismet_comment_form_privacy_notice_markup',
'<p class="akismet_comment_form_privacy_notice">' . sprintf(
__( 'This site uses Akismet to reduce spam. <a href="%s" target="_blank" rel="nofollow noopener">Learn how your comment data is processed</a>.', 'akismet' ),
'https://akismet.com/privacy/'