Comments: Use a more precise check for disallowed keys on filtered comment data.
The previous approach of running `wp_allow_comment()` twice could have unintended consequences, e.g. the `check_comment_flood` action was also triggered twice, which might lead to false-positive identification of comment flood in case there is some custom callback hooked to it, which is not expecting identical data seeing twice. This commit introduces a new function, `wp_check_comment_data()`, to specifically check for disallowed content before and after comment data is filtered. Follow-up to [59267]. Props david.binda, SergeyBiryukov. See #61827. Built from https://develop.svn.wordpress.org/trunk@59319 git-svn-id: http://core.svn.wordpress.org/trunk@58705 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
ccd2ab7f3f
commit
7b9673722e
|
@ -773,59 +773,7 @@ function wp_allow_comment( $commentdata, $wp_error = false ) {
|
||||||
return new WP_Error( 'comment_flood', $comment_flood_message, 429 );
|
return new WP_Error( 'comment_flood', $comment_flood_message, 429 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $commentdata['user_id'] ) ) {
|
return wp_check_comment_data( $commentdata );
|
||||||
$user = get_userdata( $commentdata['user_id'] );
|
|
||||||
$post_author = $wpdb->get_var(
|
|
||||||
$wpdb->prepare(
|
|
||||||
"SELECT post_author FROM $wpdb->posts WHERE ID = %d LIMIT 1",
|
|
||||||
$commentdata['comment_post_ID']
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isset( $user ) && ( $commentdata['user_id'] == $post_author || $user->has_cap( 'moderate_comments' ) ) ) {
|
|
||||||
// The author and the admins get respect.
|
|
||||||
$approved = 1;
|
|
||||||
} else {
|
|
||||||
// Everyone else's comments will be checked.
|
|
||||||
if ( check_comment(
|
|
||||||
$commentdata['comment_author'],
|
|
||||||
$commentdata['comment_author_email'],
|
|
||||||
$commentdata['comment_author_url'],
|
|
||||||
$commentdata['comment_content'],
|
|
||||||
$commentdata['comment_author_IP'],
|
|
||||||
$commentdata['comment_agent'],
|
|
||||||
$commentdata['comment_type']
|
|
||||||
) ) {
|
|
||||||
$approved = 1;
|
|
||||||
} else {
|
|
||||||
$approved = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( wp_check_comment_disallowed_list(
|
|
||||||
$commentdata['comment_author'],
|
|
||||||
$commentdata['comment_author_email'],
|
|
||||||
$commentdata['comment_author_url'],
|
|
||||||
$commentdata['comment_content'],
|
|
||||||
$commentdata['comment_author_IP'],
|
|
||||||
$commentdata['comment_agent']
|
|
||||||
) ) {
|
|
||||||
$approved = EMPTY_TRASH_DAYS ? 'trash' : 'spam';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filters a comment's approval status before it is set.
|
|
||||||
*
|
|
||||||
* @since 2.1.0
|
|
||||||
* @since 4.9.0 Returning a WP_Error value from the filter will short-circuit comment insertion
|
|
||||||
* and allow skipping further processing.
|
|
||||||
*
|
|
||||||
* @param int|string|WP_Error $approved The approval status. Accepts 1, 0, 'spam', 'trash',
|
|
||||||
* or WP_Error.
|
|
||||||
* @param array $commentdata Comment data.
|
|
||||||
*/
|
|
||||||
return apply_filters( 'pre_comment_approved', $approved, $commentdata );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1292,6 +1240,75 @@ function wp_check_comment_data_max_lengths( $comment_data ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether comment data passes internal checks or has disallowed content.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @global wpdb $wpdb WordPress database abstraction object.
|
||||||
|
*
|
||||||
|
* @param array $comment_data Array of arguments for inserting a comment.
|
||||||
|
* @return int|string|WP_Error The approval status on success (0|1|'spam'|'trash'),
|
||||||
|
* WP_Error otherwise.
|
||||||
|
*/
|
||||||
|
function wp_check_comment_data( $comment_data ) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
if ( ! empty( $comment_data['user_id'] ) ) {
|
||||||
|
$user = get_userdata( $comment_data['user_id'] );
|
||||||
|
$post_author = $wpdb->get_var(
|
||||||
|
$wpdb->prepare(
|
||||||
|
"SELECT post_author FROM $wpdb->posts WHERE ID = %d LIMIT 1",
|
||||||
|
$comment_data['comment_post_ID']
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $user ) && ( $comment_data['user_id'] == $post_author || $user->has_cap( 'moderate_comments' ) ) ) {
|
||||||
|
// The author and the admins get respect.
|
||||||
|
$approved = 1;
|
||||||
|
} else {
|
||||||
|
// Everyone else's comments will be checked.
|
||||||
|
if ( check_comment(
|
||||||
|
$comment_data['comment_author'],
|
||||||
|
$comment_data['comment_author_email'],
|
||||||
|
$comment_data['comment_author_url'],
|
||||||
|
$comment_data['comment_content'],
|
||||||
|
$comment_data['comment_author_IP'],
|
||||||
|
$comment_data['comment_agent'],
|
||||||
|
$comment_data['comment_type']
|
||||||
|
) ) {
|
||||||
|
$approved = 1;
|
||||||
|
} else {
|
||||||
|
$approved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( wp_check_comment_disallowed_list(
|
||||||
|
$comment_data['comment_author'],
|
||||||
|
$comment_data['comment_author_email'],
|
||||||
|
$comment_data['comment_author_url'],
|
||||||
|
$comment_data['comment_content'],
|
||||||
|
$comment_data['comment_author_IP'],
|
||||||
|
$comment_data['comment_agent']
|
||||||
|
) ) {
|
||||||
|
$approved = EMPTY_TRASH_DAYS ? 'trash' : 'spam';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters a comment's approval status before it is set.
|
||||||
|
*
|
||||||
|
* @since 2.1.0
|
||||||
|
* @since 4.9.0 Returning a WP_Error value from the filter will short-circuit comment insertion
|
||||||
|
* and allow skipping further processing.
|
||||||
|
*
|
||||||
|
* @param int|string|WP_Error $approved The approval status. Accepts 1, 0, 'spam', 'trash',
|
||||||
|
* or WP_Error.
|
||||||
|
* @param array $commentdata Comment data.
|
||||||
|
*/
|
||||||
|
return apply_filters( 'pre_comment_approved', $approved, $comment_data );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a comment contains disallowed characters or words.
|
* Checks if a comment contains disallowed characters or words.
|
||||||
*
|
*
|
||||||
|
@ -2279,11 +2296,15 @@ function wp_new_comment( $commentdata, $wp_error = false ) {
|
||||||
|
|
||||||
$commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error );
|
$commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error );
|
||||||
|
|
||||||
|
if ( is_wp_error( $commentdata['comment_approved'] ) ) {
|
||||||
|
return $commentdata['comment_approved'];
|
||||||
|
}
|
||||||
|
|
||||||
$commentdata = wp_filter_comment( $commentdata );
|
$commentdata = wp_filter_comment( $commentdata );
|
||||||
|
|
||||||
if ( ! in_array( $commentdata['comment_approved'], array( 'trash', 'spam' ), true ) ) {
|
if ( ! in_array( $commentdata['comment_approved'], array( 'trash', 'spam' ), true ) ) {
|
||||||
// Validate the comment again after filters are applied to comment data.
|
// Validate the comment again after filters are applied to comment data.
|
||||||
$commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error );
|
$commentdata['comment_approved'] = wp_check_comment_data( $commentdata );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( is_wp_error( $commentdata['comment_approved'] ) ) {
|
if ( is_wp_error( $commentdata['comment_approved'] ) ) {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '6.8-alpha-59318';
|
$wp_version = '6.8-alpha-59319';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
|
Loading…
Reference in New Issue