<?php /* Plugin Name: WordPress Hashcash Plugin URI: http://wordpress-plugins.feifei.us/hashcash/ Description: Client-side javascript blocks all spam bots. XHTML 1.1 compliant. Author: Elliott Back Author URI: http://elliottback.com Version: 4.6 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ function wphc_option($save = false){ if($save) { if( function_exists( 'update_site_option' ) ) { update_site_option('plugin_wp-hashcash', $save); } else { update_option('plugin_wp-hashcash', $save); } return $save; } else { if( function_exists( 'get_site_option' ) ) { $options = get_site_option('plugin_wp-hashcash'); } else { $options = get_option('plugin_wp-hashcash'); } if(!is_array($options)) $options = array(); return $options; } } /** * Install WP Hashcash */ function wphc_install () { // set our default options $options = wphc_option(); $options['comments-spam'] = $options['comments-spam'] || 0; $options['comments-ham'] = $options['comments-ham'] || 0; $options['signups-spam'] = $options['signups-spam'] || 0; $options['signups-ham'] = $options['signups-ham'] || 0; $options['key'] = array(); $options['key-date'] = 0; $options['refresh'] = 60 * 60 * 24 * 7; $options['signup_active'] = 1; $options['comments_active'] = 1; $options['attribution'] = 1; // akismet compat check if(function_exists('akismet_init')){ $options['moderation'] = 'akismet'; } else { $options['moderation'] = 'moderate'; } // validate ip / url $options['validate-ip'] = true; $options['validate-url'] = true; // logging $options['logging'] = true; // update the key wphc_option($options); wphc_refresh(); } add_action('activate_wp-hashcash/wp-hashcash.php', 'wphc_install'); add_action('activate_wp-hashcash.php', 'wphc_install'); /** * Update the key, if needed */ function wphc_refresh(){ $options = wphc_option(); if( !isset( $options[ 'signup_active' ] ) ) { wphc_install(); return; } if(time() - $options['key-date'] > $options['refresh']) { if(count($options['key']) >= 5) array_shift($options['key']); array_push($options['key'], rand(21474836, 2126008810)); $options['key-date'] = time(); wphc_option($options); } } add_action('shutdown', 'wphc_refresh'); /** * Our plugin can also have a widget */ function get_spam_ratio( $ham, $spam ) { if($spam + $ham == 0) $ratio = 0; else $ratio = round(100 * ($spam/($ham+$spam)),2); return $ratio; } function widget_ratio($options){ $signups_ham = (int)$options['signups-ham']; $signups_spam = (int)$options['signups-spam']; $ham = (int)$options['comments-ham']; $spam = (int)$options['comments-spam']; $ratio = get_spam_ratio( $ham, $spam ); $signups_ratio = get_spam_ratio( $signups_ham, $signups_spam ); $msg = "<li><span>$spam spam comments blocked out of $ham human comments. " . $ratio ."% of your comments are spam!</span></li>"; if( $signups_ham && $signups_spam ) $msg = "<li><span>$signups_spam spam signups blocked out of $signups_ham human signups. " . $signups_ratio ."% of your signups are spam!</span></li>"; return $msg; } /** * Admin Options */ add_action('admin_menu', 'wphc_add_options_to_admin'); function wphc_add_options_to_admin() { if( function_exists( 'is_site_admin' ) && !is_site_admin() ) return; if (function_exists('add_options_page')) { if( function_exists( 'is_site_admin' ) ) { add_submenu_page('wpmu-admin.php', __('WordPress Hashcash'), __('WordPress Hashcash'), 'manage_options', 'wphc_admin', 'wphc_admin_options'); } else { add_options_page('Wordpress Hashcash', 'Wordpress Hashcash', 8, basename(__FILE__), 'wphc_admin_options'); } } } function wphc_admin_options() { if( function_exists( 'is_site_admin' ) && !is_site_admin() ) return; $options = wphc_option(); if( !isset( $options[ 'signup_active' ] ) ) { wphc_install(); // MU has no activation hook $options = wphc_option(); } // POST HANDLER if($_POST['wphc-submit']){ check_admin_referer( 'wphc-options' ); if ( function_exists('current_user_can') && !current_user_can('manage_options') ) die('Current user not authorized to managed options'); $options['refresh'] = strip_tags(stripslashes($_POST['wphc-refresh'])); $options['moderation'] = strip_tags(stripslashes($_POST['wphc-moderation'])); $options['validate-ip'] = strip_tags(stripslashes($_POST['wphc-validate-ip'])); $options['validate-url'] = strip_tags(stripslashes($_POST['wphc-validate-url'])); $options['logging'] = strip_tags(stripslashes($_POST['wphc-logging'])); $options['signup_active'] = (int) $_POST['signup_active']; $options['comments_active'] = (int) $_POST['comments_active']; wphc_option($options); } // MAIN FORM echo '<style type="text/css"> .wrap h3 { color: black; background-color: #e5f3ff; padding: 4px 8px; } .sidebar { border-right: 2px solid #e5f3ff; width: 200px; float: left; padding: 0px 20px 0px 10px; margin: 0px 20px 0px 0px; } .sidebar input { background-color: #FFF; border: none; } .main { float: left; width: 600px; } .clear { clear: both; } </style>'; echo '<div class="wrap">'; echo '<div class="sidebar">'; echo '<h3>Plugin</h3>'; echo '<ul> <li><a href="http://wordpress-plugins.feifei.us/hashcash/">Plugin\'s Homepage</a></li>'; if( function_exists( 'is_site_admin' ) && is_site_admin() ) { echo '<li><a href="http://mu.wordpress.org/forums/">WordPress MU Forums</a></li>'; } echo '<li><a href="http://wordpress.org/tags/wp-hashcash">Plugin Support Forum</a></li>'; echo '</ul>'; echo '<h3>Donation</h3>'; echo '<center><form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input type="hidden" name="cmd" value="_s-xclick"> <input style="border:none;" type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"> <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1"> <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----"></form></center>'; echo '<p>Any small donation would be highly appreciated.</p>'; echo '<h3>Miscellaneous</h3>'; echo '<ul> <li><a href="http://wordpress-plugins.feifei.us/">Elliott\'s WP Plugins</a></li> <li><a href="http://ocaoimh.ie/wordpress-plugins/">Donncha\'s WP Plugins</a></li> </ul>'; echo '<h3>Statistics</h3>'; echo '<p>'.widget_ratio($options).'</p>'; echo '</div>'; echo '<div class="main">'; echo '<h2>WordPress Hashcash</h2>'; echo '<p>This is an antispam plugin that eradicates spam signups on WordPress sites. It works because your visitors must use obfuscated javascript to submit a proof-of-work that indicates they opened your website in a web browser, not a robot. You can read more about it on the <a href="http://wordpress-plugins.feifei.us/hashcash/">WordPress Hashcash plugin page</a> of my site.</p>'; echo '<h3>Standard Options</h3>'; echo '<form method="POST" action="?page=' . $_GET[ 'page' ] . '&updated=true">'; wp_nonce_field('wphc-options'); if( function_exists( 'is_site_admin' ) ) { // MU only $signup_active = (int)$options[ 'signup_active' ]; $comments_active = (int)$options[ 'comments_active' ]; echo "<p><label>Signup protection enabled: <input type='checkbox' name='signup_active' value='1' " . ( $signup_active == '1' ? ' checked' : '' ) . " /></label></p>"; echo "<p><label>Comments protection enabled: <input type='checkbox' name='comments_active' value='1' " . ( $comments_active == '1' ? ' checked' : '' ) . " /></label></p>"; } // moderation options $moderate = htmlspecialchars($options['moderation'], ENT_QUOTES); echo '<p><label for="wphc-moderation">' . __('Moderation:', 'wp-hashcash') . '</label>'; echo '<select id="wphc-moderation" name="wphc-moderation">'; echo '<option value="moderate"'.($moderate=='moderate'?' selected':'').'>Moderate</option>'; echo '<option value="akismet"'.($moderate=='akismet'?' selected':'').'>Akismet</option>'; echo '<option value="delete"'.($moderate=='delete'?' selected':'').'>Delete</option>'; echo '</select>'; echo '<br/><span style="color: grey; font-size: 90%;">The default is to place spam comments into the akismet/moderation queue. Otherwise, the delete option will immediately discard spam comments.</span>'; echo '</p>'; // refresh interval $refresh = htmlspecialchars($options['refresh'], ENT_QUOTES); echo '<p><label for="wphc-refresh">' . __('Key Expiry:', 'wp-hashcash').'</label> <input style="width: 200px;" id="wphc-refresh" name="wphc-refresh" type="text" value="'.$refresh.'" /> <br/><span style="color: grey; font-size: 90%;">Default is one week, or <strong>604800</strong> seconds.</p>'; // current key echo '<p>Your current key is <strong>' . $options['key'][count($options['key']) - 1] . '</strong>.'; if(count($options['key']) > 1) echo ' Previously you had keys '. join(', ', array_reverse(array_slice($options['key'], 0, count($options['key']) - 1))).'.'; echo '</p>'; // additional options echo '<h3>Additional options:</h3>'; $validate_ip = htmlspecialchars($options['validate-ip'], ENT_QUOTES); echo '<p><label for="wphc-validate-ip">Validate IP Address</label> <input name="wphc-validate-ip" type="checkbox" id="wphc-validate-ip"'.($validate_ip?' checked':'').'/> <br /><span style="color: grey; font-size: 90%;"> Checks if the IP address of the trackback sender is equal to the IP address of the webserver the trackback URL is referring to.</span></p>'; $validate_url = htmlspecialchars($options['validate-url'], ENT_QUOTES); echo '<p><label for="wphc-validate-url">Validate URL</label> <input name="wphc-validate-url" type="checkbox" id="wphc-validate-url"'.($validate_url?' checked':'').'/> <br /><span style="color: grey; font-size: 90%;">Retrieves the web page located at the URL included in the trackback to check if it contains a link to your blog. If it does not, it is spam!</span></p>'; // logging options echo '<h3>Logging:</h3>'; $logging = htmlspecialchars($options['logging'], ENT_QUOTES); echo '<p><label for="wphc-logging">Logging</label> <input name="wphc-logging" type="checkbox" id="wphc-logging"'.($logging?' checked':'').'/> <br /><span style="color: grey; font-size: 90%;">Logs the reason why a given comment failed the spam check into the comment body. Works only if moderation / akismet mode is enabled.</span></p>'; echo '<input type="hidden" id="wphc-submit" name="wphc-submit" value="1" />'; echo '<input type="submit" id="wphc-submit-override" name="wphc-submit-override" value="Save WP Hashcash Settings"/>'; echo '</form>'; echo '</div>'; echo '<div class="clear">'; echo '<p style="text-align: center; font-size: .85em;">© Copyright '.date('Y').' <a href="http://elliottback.com">Elliott Bäck</a></p>'; echo '</div>'; echo '</div>'; } /** * Add JS to the header */ function wphc_posthead() { if( function_exists( 'is_site_admin' ) ) { $options = wphc_option(); if( !$options['comments_active'] ) return; } if((is_single() || is_page())) wphc_addhead(); } add_action('wp_head', 'wphc_posthead'); function wphc_signuphead() { if( function_exists( 'is_site_admin' ) ) { $options = wphc_option(); if( !$options['signup_active'] ) return; } wphc_addhead(); } add_action('signup_header', 'wphc_signuphead'); function wphc_addhead() { echo "<script type=\"text/javascript\"><!--\n"; echo 'function addLoadEvent(func) { if( typeof jQuery != \'undefined\' ) { jQuery(document).ready( func ); } else if( typeof Prototype != \'undefined\' ) { Event.observe( window, \'load\', func ); } else { var oldonload = window.onload; if (typeof window.onload != \'function\') { window.onload = func; } else { window.onload = function() { if (oldonload) oldonload(); func(); } } } } '; echo wphc_getjs() . "\n"; echo "addLoadEvent(function(){var el=document.getElementById('wphc_value');if(el)el.value=wphc();});\n"; echo "//--></script>\n"; } function wphc_getjs(){ $options = wphc_option(); $val = $options['key'][count($options['key']) - 1]; $js = 'function wphc_compute(){'; switch(rand(0, 3)){ /* Addition of n times of field value / n, + modulus: Time guarantee: 100 iterations or less */ case 0: $inc = rand($val / 100, $val - 1); $n = floor($val / $inc); $r = $val % $inc; $js .= "var wphc_eax = $inc; "; for($i = 0; $i < $n - 1; $i++){ $js .= "wphc_eax += $inc; "; } $js .= "wphc_eax += $r; "; $js .= 'return wphc_eax; '; break; /* Conversion from binary: Time guarantee: log(n) iterations or less */ case 1: $binval = strrev(base_convert($val, 10, 2)); $js .= "var wphc_eax = \"$binval\"; "; $js .= 'var wphc_ebx = 0; '; $js .= 'var wphc_ecx = 0; '; $js .= 'while(wphc_ecx < wphc_eax.length){ '; $js .= 'if(wphc_eax.charAt(wphc_ecx) == "1") { '; $js .= 'wphc_ebx += Math.pow(2, wphc_ecx); '; $js .= '} '; $js .= 'wphc_ecx++; '; $js .= '} '; $js .= 'return wphc_ebx;'; break; /* Multiplication of square roots: Time guarantee: constant time */ case 2: $sqrt = floor(sqrt($val)); $r = $val - ($sqrt * $sqrt); $js .= "return $sqrt * $sqrt + $r; "; break; /* Sum of random numbers to the final value: Time guarantee: log(n) expected value */ case 3: $js .= 'return '; $i = 0; while($val > 0){ if($i++ > 0) $js .= '+'; $temp = rand(1, $val); $val -= $temp; $js .= $temp; } $js .= ';'; break; } $js .= '} wphc_compute();'; // pack bytes if( !function_exists( 'strToLongs' ) ) { function strToLongs($s) { $l = array(); // pad $s to some multiple of 4 $s = preg_split('//', $s, -1, PREG_SPLIT_NO_EMPTY); while(count($s) % 4 != 0){ $s [] = ' '; } for ($i = 0; $i < ceil(count($s)/4); $i++) { $l[$i] = ord($s[$i*4]) + (ord($s[$i*4+1]) << 8) + (ord($s[$i*4+2]) << 16) + (ord($s[$i*4+3]) << 24); } return $l; } } // xor all the bytes with a random key $key = rand(21474836, 2126008810); $js = strToLongs($js); for($i = 0; $i < count($js); $i++){ $js[$i] = $js[$i] ^ $key; } // libs function encapsulation $libs = "function wphc(){\n"; // write bytes to javascript, xor with key $libs .= "\tvar wphc_data = [".join(',',$js)."]; \n"; // do the xor with key $libs .= "\n\tfor (var i=0; i<wphc_data.length; i++){\n"; $libs .= "\t\twphc_data[i]=wphc_data[i]^$key;\n"; $libs .= "\t}\n"; // convert bytes back to string $libs .= "\n\tvar a = new Array(wphc_data.length); \n"; $libs .= "\tfor (var i=0; i<wphc_data.length; i++) { \n"; $libs .= "\t\ta[i] = String.fromCharCode(wphc_data[i] & 0xFF, wphc_data[i]>>>8 & 0xFF, "; $libs .= "wphc_data[i]>>>16 & 0xFF, wphc_data[i]>>>24 & 0xFF);\n"; $libs .= "\t}\n"; $libs .= "\n\treturn eval(a.join('')); \n"; // call libs function $libs .= "}"; // return code return $libs; } /** * Hook into the signups form */ function wphc_add_signupform(){ echo '<input type="hidden" id="wphc_value" name="wphc_value" value=""/>'; } add_action('signup_hidden_fields', 'wphc_add_signupform'); add_action('bp_after_registration_submit_buttons', 'wphc_add_signupform'); function wphc_add_commentform(){ $options = wphc_option(); switch($options['moderation']){ case 'delete': $verb = 'deleted'; break; case 'akismet': $verb = 'queued in Akismet'; break; case 'moderate': default: $verb = 'placed in moderation'; break; } echo '<div><input type="hidden" id="wphc_value" name="wphc_value" value=""/></div>'; echo '<noscript><div><small>Wordpress Hashcash needs javascript to work, but your browser has javascript disabled. Your comment will be '.$verb.'!</small></div></noscript>'; } add_action('comment_form', 'wphc_add_commentform'); /** * Validate our tag */ function wphc_check_signup_hidden_tag( $result ) { // get our options $options = wphc_option(); $spam = false; if( !strpos( $_SERVER[ 'PHP_SELF' ], 'wp-signup.php' ) ) return $result; // Check the wphc values against the last five keys $spam = !in_array($_POST["wphc_value"], $options['key']); if($spam){ $options['signups-spam'] = ((int) $options['signups-spam']) + 1; wphc_option($options); $result['errors']->add( 'blogname', __('You did not pass a spam check. Please enable JavaScript in your browser.') ); } else { $options['signups-ham'] = ((int) $options['signups-ham']) + 1; wphc_option($options); } return $result; } add_filter( 'wpmu_validate_blog_signup', 'wphc_check_signup_hidden_tag' ); add_filter( 'wpmu_validate_user_signup', 'wphc_check_signup_hidden_tag' ); function wphc_check_signup_for_bp(){ global $bp; // get our options $options = wphc_option(); $spam = false; // Check the wphc values against the last five keys $spam = !in_array($_POST["wphc_value"], $options['key']); if($spam){ $options['signups-spam'] = ((int) $options['signups-spam']) + 1; wphc_option($options); $bp->signup->errors['spam'] = __('You did not pass a spam check. Please enable JavaScript in your browser.'); } else { $options['signups-ham'] = ((int) $options['signups-ham']) + 1; wphc_option($options); } } add_action('bp_signup_validate', 'wphc_check_signup_for_bp'); function wphc_error_hook_register_page(){ do_action('bp_spam_errors'); } add_action('bp_before_register_page', 'wphc_error_hook_register_page'); function wphc_check_hidden_tag($comment) { // admins can do what they like if( is_admin() ) return $comment; // get our options $type = $comment['comment_type']; $options = wphc_option(); $spam = false; if($type == "trackback" || $type == "pingback"){ // check the website's IP against the url it's sending as a trackback if($options['validate-ip']){ $server_ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; $web_ip = gethostbyname(parse_url($comment['comment_author_url'], PHP_URL_HOST)); $ipv = $server_ip != $web_ip; $spam = $spam || ($ipv); if($options['logging'] && $ipv) $comment['comment_content'] .= "\n\n[WORDPRESS HASHCASH] The comment's server IP (".$server_ip.") doesn't match the" . " comment's URL host IP (".$web_ip.") and so is spam."; } // look for our link in the page itself if(!$spam && $options['validate-url']){ if(!class_exists('Snoopy')) require_once( ABSPATH . WPINC . '/class-snoopy.php' ); $permalink = get_permalink($comment['comment_post_ID']); $permalink = preg_replace('/\/$/', '', $permalink); $snoop = new Snoopy; if (@$snoop->fetchlinks($comment['comment_author_url'])){ $found = false; if( !empty( $snoop->results ) ) { foreach($snoop->results as $url){ $url = preg_replace('/(\/|\/trackback|\/trackback\/)$/', '', $url); if($url == $permalink) $found = true; } } if($options['logging'] && !$found) $comment['comment_content'] .= "\n\n[WORDPRESS HASHCASH] The comment's actual post text did not contain your blog url (".$permalink.") and so is spam."; $spam = $spam || !$found; } else { $spam = true; if($options['logging']) $comment['comment_content'] .= "\n\n[WORDPRESS HASHCASH] Snoopy failed to fetch results for the comment blog url (".$comment['comment_author_url'].") with error '".$snoop->error."' and so is spam."; } } } else { // Check the wphc values against the last five keys $spam = !in_array($_POST["wphc_value"], $options['key']); if($options['logging'] && $spam) $comment['comment_content'] .= "\n\n[WORDPRESS HASHCASH] The poster sent us '".intval($_POST["wphc_value"])." which is not a hashcash value."; } if($spam){ $options['comments-spam'] = ((int) $options['comments-spam']) + 1; wphc_option($options); switch($options['moderation']){ case 'delete': add_filter('comment_post', create_function('$id', 'wp_delete_comment($id); die(\'This comment has been deleted by WP Hashcash\');')); break; case 'akismet': add_filter('pre_comment_approved', create_function('$a', 'return \'spam\';')); break; case 'moderate': default: add_filter('pre_comment_approved', create_function('$a', 'return 0;')); break; } } else { $options['comments-ham'] = ((int) $options['comments-ham']) + 1; wphc_option($options); } return $comment; } add_filter('preprocess_comment', 'wphc_check_hidden_tag'); ?>