奇淫技巧

WordPress防御垃圾评论

前言

有时候早上起来一看WordPress后台,发现一堆评论,美滋滋的想着很热闹嘛,结果一看,全是垃圾评论。这对于博主以及访客来讲,这是一个很差的体验。

解决

那么,对于国内WordPress垃圾评论解决方法有很多:
第一个就是用WordPress默认自带的防垃圾评论Akismet,说实话这个插件的确是首选,效果很好,但使用过程中发现它写入很多数据库,并且占用很大的机器资源,导致网站日渐卡顿,这不行,不存在的,所以这个不考虑。
第二个是滑动或者是解锁评论的插件,说实话这个比起上面或者是下面那几个方法好多了,也没说好说的。
第三个就是验证码插件,所谓的验证码插件就是大家见到的输入验证码才能进入下一步操作,在用户体验上面来说,这是最差的体验,比起其他方法要动的地方多得多,故不考虑。
第四个方法就是现在绝大部分网站所用到的Some Chinese Please!他的简介是这样说的:这是为用为中文写作的朋友准备的一款防御spam插件。<br></br> 它可以有效地拦截内容中不带有中文字的comment和trackback(pingback),不写入数据库中,可有效地减小spam对blog服务器的无谓使用。
从简介来看对于国内的环境的确很完美,但唯一的区别就是歪果仁如果想评论的话…可能会炸的。
对于以上总结这么多的,要么自增一个选项,要么修改评论机制,都不是合适我的胃口。

方案

新方案:

新建php文件:

 $spicy_send_spam_comment_to_admin,
    'allow_trackbacks' => $spicy_allow_trackbacks,
    'admin_email' => get_option('admin_email'),
    'log_spam_comment' => $spicy_log_spam_comment
);

function spicy_enqueue_script() {
    global $withcomments; // WP flag to show comments on all pages
    if ((is_singular() || $withcomments) && comments_open()) { // load script only for pages with comments form
        wp_enqueue_script('anti-spam-script', get_template_directory_uri() .'/js/spam.js', null, SPICY_VERSION, true);
    }
}
add_action('wp_enqueue_scripts', 'spicy_enqueue_script');


function spicy_form_part() {
    global $spicy_settings;
    $rn = "\r\n"; // .chr(13).chr(10)

    if ( ! is_user_logged_in()) { // add anti-spam fields only for not logged in users
        echo '

'.$rn; // question (hidden with js) echo ' '.$rn; // empty field (hidden with css); trap for spammers because many bots will try to put email or url here } } add_action('comment_form', 'spicy_form_part'); // add anti-spam inputs to the comment form function spicy_check_comment($commentdata) { global $spicy_settings; $rn = "\r\n"; // .chr(13).chr(10) extract($commentdata); $spicy_pre_error_message = 'Go back and try again.

'; $spicy_error_message = ''; if (($spicy_settings['send_spam_comment_to_admin']) || ($spicy_settings['log_spam_comment'])) { // if sending email to admin is enabled or loging $post = get_post($comment->comment_post_ID); $spicy_message_spam_info = 'Spam for post: "'.$post->post_title.'"' . $rn; $spicy_message_spam_info .= get_permalink($comment->comment_post_ID) . $rn.$rn; $spicy_message_spam_info .= 'IP: ' . $_SERVER['REMOTE_ADDR'] . $rn; $spicy_message_spam_info .= 'User agent: ' . $_SERVER['HTTP_USER_AGENT'] . $rn; $spicy_message_spam_info .= 'Referer: ' . $_SERVER['HTTP_REFERER'] . $rn.$rn; $spicy_message_spam_info .= 'Comment data:'.$rn; // lets see what comment data spammers try to submit foreach ($commentdata as $key => $value) { $spicy_message_spam_info .= '$commentdata['.$key. '] = '.$value.$rn; } $spicy_message_spam_info .= $rn.$rn; $spicy_message_spam_info .= 'Post vars:'.$rn; // lets see what post vars spammers try to submit foreach ($_POST as $key => $value) { $spicy_message_spam_info .= '$_POST['.$key. '] = '.$value.$rn; } $spicy_message_spam_info .= $rn.$rn; $spicy_message_spam_info .= 'Cookie vars:'.$rn; // lets see what cookie vars spammers try to submit foreach ($_COOKIE as $key => $value) { $spicy_message_spam_info .= '$_COOKIE['.$key. '] = '.$value.$rn; } $spicy_message_spam_info .= $rn.$rn; $spicy_message_append = '-----------------------------'.$rn; $spicy_message_append .= 'This is spam comment rejected by Anti-spam plugin - wordpress.org/plugins/anti-spam/' . $rn; $spicy_message_append .= 'You may edit "anti-spam.php" file and disable this notification.' . $rn; $spicy_message_append .= 'You should find "$spicy_send_spam_comment_to_admin" and make it equal to "false".' . $rn; } if ( ! is_user_logged_in() && $comment_type != 'pingback' && $comment_type != 'trackback') { // logged in user is not a spammer $spam_flag = false; $antspm_q = ''; if (isset($_POST['antspm-q'])) { $antspm_q = trim($_POST['antspm-q']); } $antspm_d = ''; if (isset($_POST['antspm-d'])) { $antspm_d = trim($_POST['antspm-d']); } $antspm_e = ''; if (isset($_POST['antspm-e-email-url-website'])) { $antspm_e = trim($_POST['antspm-e-email-url-website']); } if ( $antspm_q != date('Y') ) { // year-answer is wrong - it is spam if ( $antspm_d != date('Y') ) { // extra js-only check: there is no js added input - it is spam $spam_flag = true; if (empty($antspm_q)) { // empty answer - it is spam $spicy_error_message .= 'Error: empty answer. ['.esc_attr( $antspm_q ).']
'.$rn; } else { $spicy_error_message .= 'Error: answer is wrong. ['.esc_attr( $antspm_q ).']
'.$rn; } } } if ( ! empty($antspm_e)) { // trap field is not empty - it is spam $spam_flag = true; $spicy_error_message .= 'Error: field should be empty. ['.esc_attr( $antspm_e ).']
'.$rn; } if ($spam_flag) { // it is spam $spicy_error_message .= 'Comment was blocked because it is spam.
'; if ($spicy_settings['send_spam_comment_to_admin']) { $spicy_subject = 'Spam comment on site ['.get_bloginfo('name').']'; // email subject $spicy_message = ''; $spicy_message .= $spicy_error_message . $rn.$rn; $spicy_message .= $spicy_message_spam_info; // spam comment, post, cookie and other data $spicy_message .= $spicy_message_append; @wp_mail($spicy_settings['admin_email'], $spicy_subject, $spicy_message); // send spam comment to admin email } if ($spicy_settings['log_spam_comment']) { $spicy_message = $rn.$rn.'========== ========== =========='.$rn.$rn; $spicy_message .= $spicy_error_message . $rn.$rn; $spicy_message .= $spicy_message_spam_info; // spam comment, post, cookie and other data spicy_log( $spicy_message ); } spicy_counter_stats(); wp_die( $spicy_pre_error_message . $spicy_error_message ); // die - do not send comment and show errors } } if ( ! $spicy_settings['allow_trackbacks']) { // if trackbacks are blocked (pingbacks are alowed) if ($comment_type == 'trackback') { // if trackbacks ( || $comment_type == 'pingback') $spicy_error_message .= 'Error: trackbacks are disabled.
'; if ($spicy_settings['send_spam_comment_to_admin']) { // if sending email to admin is enabled $spicy_subject = 'Spam trackback on site ['.get_bloginfo('name').']'; // email subject $spicy_message = ''; $spicy_message .= $spicy_error_message . $rn.$rn; $spicy_message .= $spicy_message_spam_info; // spam comment, post, cookie and other data $spicy_message .= $spicy_message_append; @wp_mail($spicy_settings['admin_email'], $spicy_subject, $spicy_message); // send trackback comment to admin email } spicy_counter_stats(); wp_die($spicy_pre_error_message . $spicy_error_message); // die - do not send trackback } } return $commentdata; // if comment does not looks like spam } if ( ! is_admin()) { add_filter('preprocess_comment', 'spicy_check_comment', 1); }

然后把该文件引入function.php

require get_template_directory() . '/path/to/spam-comment.php';

以下方案已过时,不适合现在WorPress平台。

经过fuzz博主的提醒和指导:他的意思大致是把真实的评论框展示给游客,对于抓取的机器人展示的隐藏区域的评论框。
新建一个php文件:

<?php
class spam_comment {

    protected $insertAt;
    protected $label_list = array( 'Name', 'Email', 'Website', 'Comment' );
    protected $icon_list = array( 'user', 'envelope', 'home', 'comment' );
    protected $label;
    protected $addOn;
    protected $salt;
    protected $hideClass;
    protected $nameRegex = '/name="[a-z0-9]*"/i';
    protected $idRegex = '/id="[a-z0-9]*"/i';
    protected $forRegex = '/for="[a-z0-9]*"/i';
    protected $approvedComment = '';

    function __construct() {
        add_filter( 'comment_form_before_fields', array( &$this, 'spicy_init' ) );
        add_filter( 'comment_form_field_author', array( &$this, 'spicy_encrypt_author' ) );
        add_filter( 'comment_form_field_email', array( &$this, 'spicy_encrypt_email' ) );
        add_filter( 'comment_form_field_url', array( &$this, 'spicy_encrypt_url' ) );
        add_filter( 'comment_form_field_comment', array( &$this, 'spicy_encrypt_comment' ) );
        add_action( 'pre_comment_approved', array( &$this, 'spicy_check_form' ) );
        add_action( 'pre_comment_on_post', array( &$this, 'spicy_pre_post' ) );
        add_action( 'comment_form', array( &$this, 'spicy_hidden_field_and_script' ) );
    }

    function spicy_init() {
        $this->insertAt  = rand() & 3;
        $this->label     = rand() & 3;
        $this->addOn     = substr( sha1( time() . $this->salt ), 0, 6 );
        $this->salt      = '随机密匙';
        $this->hideClass = 'spicy-comment';
    }

    function spicy_insertHoneyPot() {
        $hp_field =
            '<div class="' . strtolower( $this->hideClass ) . '">' .
            '<label for="' . strtolower( $this->label_list[ $this->label ] ) . '">' .
            $this->label_list[ $this->label ] .
            '</label>' .
                    '<input type="text" name="' . strtolower( $this->label_list[ $this->label ] ) . '" id="' . strtolower( $this->label_list[ $this->label ] ) . '" value="">' .
                    '<label  for="' . strtolower( $this->label_list[ $this->label ] ) . '">' . esc_html__('辣鸡评论你来写') . '</label>' .
            '</div>';

        return $hp_field;
    }

    private function spicy_make_field( $unique, $addOn = false ) {
        if ( $addOn === false ) {
            $addOn = $this->addOn;
        }

        return md5( $unique . $addOn );
    }

    private function spicy_replace_name_id( $unique, $field ) {
        $field_name = $this->spicy_make_field( $unique );
        $field      = preg_replace( $this->nameRegex, 'name="' . $field_name . '"', $field );
        $field      = preg_replace( $this->idRegex, 'id="' . $field_name . '"', $field );
        $field      = preg_replace( $this->forRegex, 'for="' . $field_name . '"', $field );

        return $field;
    }

    function spicy_encrypt_author( $author_field ) {
        $author_field = $this->spicy_replace_name_id( 'author', $author_field );
        if ( $this->insertAt == 0 ) {
            $author_field = $this->spicy_insertHoneyPot() . $author_field;
        }

        return $author_field;
    }

    function spicy_encrypt_email( $email_field ) {
        $email_field = $this->spicy_replace_name_id( 'email', $email_field );
        if ( $this->insertAt == 1 ) {
            $email_field = $this->spicy_insertHoneyPot() . $email_field;
        }

        return $email_field;
    }

    function spicy_encrypt_url( $url_field ) {
        $url_field = $this->spicy_replace_name_id( 'url', $url_field );
        if ( $this->insertAt == 2 ) {
            $url_field = $this->spicy_insertHoneyPot() . $url_field;
        }

        return $url_field;
    }

    function spicy_encrypt_comment( $comment_field ) {
        $comment_field = $this->spicy_replace_name_id( 'comment', $comment_field );
        if ( $this->insertAt == 3 ) {
            $comment_field = $this->spicy_insertHoneyPot() . $comment_field;
        }

        return $comment_field;
    }

    function spicy_pre_post() {
        $output = base64_decode( $_POST['enc-type'] );
        $output = rtrim( $output, '' );
        $addOn  = substr( $output, 0, - 1 );
        if ( ! empty( $_POST[ strtolower( $this->label_list[ substr( $output, - 1, 1 ) ] ) ] ) ) {
            $this->approved = 'spam';
        }
        $author           = $this->spicy_make_field( 'author', $addOn );
        $_POST['author']  = $_POST[ $author ];
        $email            = $this->spicy_make_field( 'email', $addOn );
        $_POST['email']   = $_POST[ $email ];
        $url              = $this->spicy_make_field( 'url', $addOn );
        $_POST['url']     = $_POST[ $url ];
        $comment          = $this->spicy_make_field( 'comment', $addOn );
        $_POST['comment'] = $_POST[ $comment ];
    }

    function spicy_check_form( $approved ) {
        if ( isset( $this->approved ) ) {
            if ( $this->approved == 'spam' ) {
                return 'spam';
            }
        }

        return $approved;
    }

    function spicy_hidden_field_and_script() {
        $output = base64_encode( $this->addOn . $this->label );
        echo '<input type="hidden" name="enc-type" value="' . $output . '"/>';
    }

}

new spam_comment();

第31行的$this->salt = '随机密匙';改值随便写,位数不限
第32行的$this->hideClass = 'spicy-comment';是隐藏区域的评论框类名,需要在style.css加入:

div.spicy-comment {
    display: none;
}

然后把该文件引入function.php

require get_template_directory() . '/path/to/spam-comment.php';

然后看评论区域的源代码是否生效:

<form action="http://wordpress.test/wp-comments-post.php" method="post" id="commentform" class="comment-form" novalidate="">
  <p class="comment-tips">理性发言,共建美好精神家园!</p>
  <textarea placeholder="Write a response..." maxlength="65525" aria-required="true" required="required" name="06d4cd63bde972fc66a0aed41d2f5c51" class="commentForm commentbody" id="06d4cd63bde972fc66a0aed41d2f5c51" rows="5" tabindex="4"></textarea>
  <input type="text" placeholder="Your Name *" name="fded2aebdfa00cca98ea9f19e3135560" id="fded2aebdfa00cca98ea9f19e3135560" class="commentForm" value="" size="22" tabindex="1" aria-required="true" />
  <input type="text" placeholder="Your Email *" name="bd547ffd2d698814d706465f439ceb46" id="bd547ffd2d698814d706465f439ceb46" class="commentForm commentLeft" value="" size="22" tabindex="1" aria-required="true" />
  <div class="spicy-comment">
    <label for="name">Name</label>
    <input type="text" name="name" id="name" value="" />
    <label for="name">辣鸡评论你来写</label></div>
  <input type="text" placeholder="Your Site" name="04bb297aaa4045ac67b3986b954ec707" id="04bb297aaa4045ac67b3986b954ec707" class="commentForm commentLeft" value="" size="22" tabindex="1" />
  <p class="form-submit">
    <input name="submit" type="submit" id="submit" class="submit" value="发表评论" />
    <input type="hidden" name="comment_post_ID" value="93" id="comment_post_ID" />
    <input type="hidden" name="comment_parent" id="comment_parent" value="0" /></p>
  <input type="hidden" name="enc-type" value="ZTA0MzliMA==" /></form>

如上的表单id全部变成密匙类型那么起效了,可以防御机器人垃圾留言。

本站内容遵循知识共享署名-非商业性使用-相同方式共享4.0 国际许可协议

转载原创文章请注明转自:WordPress防御垃圾评论

“WordPress防御垃圾评论”有4个点评

      1. 你好!很高兴你及时更新了!不过用在我现用的主题上会导致WP 500,比老代码要严重呢,如果有需要我可以提供VPS Admin……
        另外不得不说,您的编辑器很好用,让我用WP又多了一个理由呢……

发表评论

理性发言,共建美好精神家园!