- b2evolution CMS Support Forums
- b2evolution Support
- Plugins & Extensions
- [HACK] WhiteList the good guys
1 edb Sep 12, 2005 06:31
DISCLAIMER: I have no proof this does anything good. I *think* if you whitelist the good guys and save them the stigma of being held up against the blacklist you're saving something. Time for your visitors? Server cycles? I don't know and I have no proof.
PREAMBLE: I get lots of one-shot referers due to the popularity of the kubrick2evo skin. Before I dumped my goodrefs table in favor of a whitelist table I had 238 domains identified as good guys. THAT is why domains become trusted then whitelisted.
Step 1: build a new table. The SQL string for it is:
CREATE TABLE `YOUR_DB_NAME_HERE`.`evo_whitelist` ( `ID` int( 10 ) unsigned NOT NULL AUTO_INCREMENT , `BaseDomain` varchar( 250 ) default NULL , `Status` varchar( 4 ) NOT NULL default '', PRIMARY KEY ( `ID` ) ) TYPE = MYISAM ;
Step 2: tell b2evolution this table exists in conf/_advanced.php:
$tableposts = 'evo_posts';
$tableusers = 'evo_users';
$tablesettings = 'evo_settings';
$tablecategories = 'evo_categories';
$tablecomments = 'evo_comments';
$tableblogs = 'evo_blogs';
$tablepostcats = 'evo_postcats';
$tablehitlog = 'evo_hitlog';
$tableantispam = 'evo_antispam';
$tablegroups = 'evo_groups';
$tableblogusers = 'evo_blogusers';
$tablelocales = 'evo_locales';
$tablewhitelist = 'evo_whitelist';
and
'T_posts' => $tableposts ,
'T_users' => $tableusers ,
'T_settings' => $tablesettings ,
'T_categories' => $tablecategories ,
'T_comments' => $tablecomments ,
'T_blogs' => $tableblogs ,
'T_postcats' => $tablepostcats ,
'T_hitlog' => $tablehitlog ,
'T_antispam' => $tableantispam ,
'T_groups' => $tablegroups ,
'T_blogusers' => $tableblogusers ,
'T_locales' => $tablelocales ,
'T_whitelist' => $tablewhitelist ,
In both cases the last line is the new stuff.
Step 3: add a new tab in your back office by editing admin/_menutop.php. The tabs begin around line 189 with <ul class="tabs"> so decide where you want the new tab and add the following there:
if( $current_User->check_perm( 'spamblacklist', 'view' ) )
{
if( $admin_tab == 'whitelist' )
echo '<li class="current">';
else
echo '<li>';
echo '<a href="whitelist.php" >', T_('White List'), '</a></li>';
}
Step 5: Forget about step 4 - it was stupid. Save the following as "whitelist.php" in your admin folder:
<?php
/**
* This controls the whitelist.
*
* b2evolution - {@link http://b2evolution.net/}
* Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
* @copyright (c)2003-2004 by Francois PLANQUE - {@link http://fplanque.net/}
*
* Created by EdB {http://wonderwinds.com}
*
* @package admin
*/
require_once( dirname(__FILE__).'/_header.php' );
$admin_tab = 'whitelist';
$admin_pagetitle = T_('View Whitelist for Blog:');
param( 'update', 'string' );
param( 'approve', 'string' );
param( 'status', 'string' );
param( 'remove', 'string' );
param( 'show', 'string', 'referers' );
require(dirname(__FILE__) . '/_menutop.php'); ?>
<a href="whitelist.php?show=<?php echo $show ?>&blog=0" class="<?php echo ( 0 == $blog ) ? 'CurrentBlog' : 'OtherBlog' ?>"><?php echo T_('None') ?></a>
<?php
for( $curr_blog_ID=blog_list_start('stub');
$curr_blog_ID!=false;
$curr_blog_ID=blog_list_next('stub') )
{
if( ! $current_User->check_perm( 'blog_post_statuses', 'any', false, $curr_blog_ID ) ) continue;
?>
<a href="whitelist.php?show=<?php echo $show ?>&blog=<?php echo $curr_blog_ID ?>" class="<?php echo ( $curr_blog_ID == $blog ) ? 'CurrentBlog' : 'OtherBlog' ?>"><?php blog_list_iteminfo('shortname') ?></a>
<?php
}
require( dirname(__FILE__) . '/_menutop_end.php' );
// Check permission:
$current_User->check_perm( 'stats', 'view', true );
if( ! $current_User->check_perm( 'blog_post_statuses', 'any', false, $blog ) && $current_User->get('level') < 10 ) {
echo '<p>'.T_('You do not have permission to view that blog\'s whitelist.').'</p>';
require( dirname(__FILE__).'/_footer.php' );
exit;
} ?>
<ul class="hack">
<li><!-- Yes, this empty UL is needed! It's a DOUBLE hack for correct CSS display --></li>
</ul>
<?php // this is where approving domains happens
if( $approve != '' ) {
$sql = "INSERT INTO $tablewhitelist( BaseDomain, Status ) VALUES( '$approve', '$status' )";
$DB->query( $sql );
$approve = '';
$status = '';
} ?>
<?php // this is where updating status happens
if( $update != '' ) {
$sql = "UPDATE $tablewhitelist SET Status = '$status' WHERE BaseDomain = '$update'";
$DB->query( $sql );
$update = '';
$status = '';
} ?>
<?php // this is where removing domains happens
if( $remove != '' ) {
$sql = "DELETE FROM $tablewhitelist WHERE BaseDomain = '$remove'";
$DB->query( $sql );
$remove = '';
} ?>
<div class="tabbedpanelblock">
<h2><?php echo T_('Top referers') ?>:</h2>
<?php refererList(99,'global',0,0,"'no'",'baseDomain',$blog,true);
if( count( $res_stats ) ) { ?>
<table class="grouped" cellspacing="0">
<thead>
<tr>
<th><?php echo T_('Referer') ?></th>
<th><?php echo T_('Referals') ?></th>
<th><?php echo T_('percentage') ?></th>
<?php if( $current_User->check_perm( 'spamblacklist', 'edit' ) ) { ?>
<th><?php echo T_('Ban!') ?></th>
<?php } ?>
<th><?php echo T_('Approve! (trust or whitelist)') ?></th>
</tr>
</thead>
<tbody>
<?php
$count = 0;
foreach( $res_stats as $row_stats ) { ?>
<tr <?php if( $count%2 == 1 ) echo 'class="odd"'; ?>>
<td class="firstcol"><a href="<?php stats_referer() ?>"><?php stats_basedomain() ?></a></td>
<td class="right"><?php stats_hit_count() ?></td>
<td class="right"><?php stats_hit_percent() ?></td>
<?php if( $current_User->check_perm( 'spamblacklist', 'edit' ) ) { ?>
<td align="center"><a href="b2antispam.php?action=ban&keyword=<?php echo urlencode( stats_basedomain(false) ) ?>" title="<?php echo T_('Ban this domain!') ?>"><img src="img/noicon.gif" class="middle" alt="<?php echo /* TRANS: Abbrev. */ T_('Ban') ?>" title="<?php echo T_('Ban this domain!') ?>" /></a></td>
<?php } ?>
<td>
<?php
$this_one_is = stats_basedomain( false );
$sql = "SELECT BaseDomain, Status FROM $tablewhitelist WHERE BaseDomain = '$this_one_is'";
$results = $DB->get_results( $sql, ARRAY_A );
if( $results ) {
foreach( $results as $is_in_table ) { ?>
<a href="whitelist.php?remove=<?php echo $this_one_is; ?>" title="<?php echo T_('Remove from WhiteList table!') ?>"><img src="img/xross.gif" class="middle" alt="<?php echo T_('Remove from WhiteList table!') ?>" title="<?php echo T_('Remove from WhiteList table!') ?>" /></a>
<?php if( $is_in_table['Status'] == 'white' ) {
echo 'WhiteListed!';
} else {
echo 'Trusted! '; ?>
<a href="whitelist.php?update=<?php echo $this_one_is; ?>&status=white" title="<?php echo T_('WhiteList this domain!') ?>"><img src="img/tick.gif" class="middle" alt="<?php echo T_('WhiteList this domain!') ?>" title="<?php echo T_('WhiteList this domain!') ?>" /> <?php echo T_('WhiteList this domain!') ?></a>
<?php
}
}
} else {
if( $current_User->check_perm( 'spamblacklist', 'edit' ) ) { ?>
<a href="whitelist.php?approve=<?php echo $this_one_is; ?>&status=trust" title="<?php echo T_('Trust this domain!') ?>"><img src="img/tick.gif" class="middle" alt="<?php echo T_('Trust this domain!') ?>" title="<?php echo T_('Trust this domain!') ?>" /> <?php echo T_('Trust this domain!') ?></a>
<a href="whitelist.php?approve=<?php echo $this_one_is; ?>&status=white" title="<?php echo T_('WhiteList this domain!') ?>"><img src="img/tick.gif" class="middle" alt="<?php echo T_('WhiteList this domain!') ?>" title="<?php echo T_('WhiteList this domain!') ?>" /> <?php echo T_('WhiteList this domain!') ?></a>
<?php }
} ?>
</td>
</tr>
<?php
$count++;
} // End stat loop ?>
</tbody>
</table>
<?php } ?>
</div>
<?php
require( dirname(__FILE__).'/_footer.php' );
?>
Step 6: Edit your b2evocore/_functions_hitlog.php file in two places. First at line 39 find something like this and add a new global:
global $stats_autoprune, $tablewhitelist;
Second at line 81 find where it searches the blacklist and make it check the whitelist first:
// Check the whitelist, then maybe the blacklist
$query = "SELECT BaseDomain FROM $tablewhitelist WHERE '".$_SERVER['HTTP_REFERER']."' LIKE CONCAT('%',BaseDomain,'%') AND Status = 'white'";
$is_a_good_guy = $DB->get_row( $query );
if( !$is_a_good_guy ) { // SEARCH BLACKLIST if it's not a good guy
foreach( $blackList as $site ) {
if( strpos( $ref, $site ) !== false ) {
// $ignore = 'blacklist';
debug_log( 'Hit Log: '. T_('referer ignored'). ' ('. T_('BlackList'). ')');
return;
}
}
}
Step 9: You count your way and I'll count mine okay? Add the following to your conf/hacks.php file, and if you don't have one then make one and b2evolution will read it.
/**
* Allow whitelisted domains to refer this visitor
* Cloned from a hack by Isaac Z. Schlueter
**/
if( !empty($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'],$baseurl) !== 0 ) {
$is_a_good_guy = $DB->get_row("select BaseDomain from $tablewhitelist where '" . $_SERVER['HTTP_REFERER'] . "' like concat('%',BaseDomain,'%') AND Status = 'white'");
if( !$is_a_good_guy ) {
/**
* Bounce all referrers who are blacklisted, by Isaac Z. Schlueter
* http://forums.b2evolution.net/viewtopic.php?t=4512
**/
$is_a_spammer = $DB->get_row("select aspm_ID, aspm_string from $tableantispam where '" . $_SERVER['HTTP_REFERER'] . "' like concat('%',aspm_string,'%')");
if( $is_a_spammer ) {
header('HTTP/1.0 403 Forbidden');
?>
<html><head><title>Stop Referrer Spam!</title>
</head><body>
<p>You are being denied access to this page because you have been referred here by a known spammer: [<?php echo $_SERVER['HTTP_REFERER'] ?>].</p>
<p>If you have reached this page in error, feel free to <a href="<?php echo $baseurl . $ReqURL ?>">bypass this message</a> with our apologies. Please leave a comment telling us to stop blacklisting sites matching [<?php echo $is_a_spammer->aspm_string ?>] so that this doesn't happen again.</p>
<p>Thank you, and sorry for the inconvenience.</p>
<p style="text-align:center">--The Management</p>
</body></html>
<?php
die();
}
}
}
The frequent hacker will notice it looks like Isaac's auto-403 hack is inside my whitelist hack, and it is. IF you are already using Isaac's hack replace that with this. You can, of course, use Isaac's version of text if you prefer. I decided to cut as many bytes as I could from it, even though I know it could be further reduced.
Those who do not have a conf/hacks.php file please be aware you need to add a first line "<?php " and a last line "?>" to the code pasted above.
SUMMARY: Now you have a new tab in your back office - the White List tab. It will show you up to 99 of your top referers. You will be able to "trust" or "whitelist" them. If you trust them now you can upgrade them to whitelist later, and in either case you can remove them from your whitelist table. Trusted sites are nothing more than a way to say "I checked this site and it's not a spammer but it's not a whitelist either". Ideally your whitelist will be a bit shorter than every single domain name that refers traffic your way, but that may be a situation unique to people who have their link on a popular skin. Once a site is whitelisted a visitor from that site will NOT be subjected to the blacklist comparison in both hacks.php (which happens almost immediately upon initialization) and when the log_hit function is triggered. That's all this does - tells you that you already know the site and save visitors from those sites a few microseconds (not that I have proof of that eh?).
3 edb Sep 12, 2005 16:10
Topanga wrote:
I would use the white list to use them - and only them - as my recent referrers/top referrers contacts.
That way you can show them again, without having to worry that spam/porn/poker/medical sites are shown.
You mean the stats on the sidebar and/or the disp=stats page? When I read this I thought I could join evo_hitlog and evo_whitelist to only allow trusted and whitelisted sites in those displays.
Topanga wrote:
The whitelist can be used also for comments.
When 'moderating comments' will be ready for publish, comments from a whitelist user, do not have to be validated.
That'd be a good idea, except not all commenters will be using domains and maybe the ones that are might not be refering you. I am not familiar with all the tables, but maybe a field for "trusted" in the user table that you could set to 'yes' after you like a certain commenter. Force them to register, but then you have to trust them to become un-moderated commenters?
Topanga wrote:
I use my stats page, to check for spammers.
Well... sites that are on my whitelist or on my trusted-list, are not shown on that particular page that I would use to check for spammers/trusted sites
Do you mean the stats tab in your back office? I used to have my goodrefs list at the bottom of my stats tab. I think that was better than on my whitelist tab because it made spammer hunting easier. Then again I can open the new referer from the whitelist tab, and either trust/whitelist or ban them from there.
Also I'm thinking maybe I join the whitelist into the 'referer' part of the stats tab so that they are NOT shown there at all. Then the stats-referer tab would only show sites you don't know yet. Almost all would be spammers then?
I would use the white list to use them - and only them - as my recent referrers/top referrers contacts.
That way you can show them again, without having to worry that spam/porn/poker/medical sites are shown.
The whitelist can be used also for comments.
When 'moderating comments' will be ready for publish, comments from a whitelist user, do not have to be validated.
I use my stats page, to check for spammers.
Well... sites that are on my whitelist or on my trusted-list, are not shown on that particular page that I would use to check for spammers/trusted sites
If it saves microseconds, I don't care. As long as it's not taking more time, I'm ok.