Today is a good day to code

Preventing Comment Spam With Spamhaus in ColdFusion and Java

Posted: December 31st, 1969 | Author: | Filed under: ColdFusion, Programming | Tags: , , , , | 3 Comments »

Preventing Comment Spam With Spamhaus in ColdFusion and Java

Recently I turned comments on again for my blog, but I started getting hammered with spam comments so I looked into trying to figure out how to stop spammers.

Most people rely on some type of image based spam prevention. This is probably performance wise the best solution, the problem is when people with poor eyesight come in, or actual people come to spam your site. This solution doesn’t prevent that scenario.

A client of mine got me to look into SPF for protecting everyone else from someone masquerading as us. That somehow led me to spamhaus again. I had always thought of using them for spam filtering, but what I didn’t know is that you can use them for web submission protection. On the site, I learned that implementing their blacklist filtering is really easy to implement. Basically the way they work is that you supply part of your visitor, whether they are sending an email on port 25 or whether they are visiting on port 80, since Spamhaus includes their web site on their black list, if someone is sending spam mail, they will return for an http request.

Basically you have to send a request over to Spamhaus’ zen DNS server. If it returns a value, then they are a spammer, or at least they are listed at Spamhaus as a spammer. The method you use is you reverse the bytes of the IP address, for example if the IP address is 2.3.4.5 then you would send a DNS request over to Spamhaus like 5.4.3.2.zen.spamhaus.org. For Java and ColdFusion, I use InetAddress, but there are methods in every language to perform these tasks.

To do this in ColdFusion you could use code that looks like this:


<cfset address = CGI.REMOTE_ADDR />

<cfset addressArr = listToArray(address,".") />

<cfset newArray = ArrayNew(1) />

<cfset newArray[1] = addressArr[4] />

<cfset newArray[2] = addressArr[3] />

<cfset newArray[3] = addressArr[2] />

<cfset newArray[4] = addressArr[1] />

<cftry>

<cfset inet = CreateObject("java", "java.net.InetAddress") />

<cfset inet = inet.getByName(arrayToList(newArray,".") & ".zen.spamhaus.org") />

<cset hostName = inet.getHostName() />

<cfif hostName NEQ "">

<cfreturn />

</cfif>

<cfcatch type="any">

<!-- do nothing -->

</cfcatch>

</cftry>

To explain, in the first line you are starting a cftry / cfcatch block. The reason for this is if the visitor’s server is clean, it will throw an error because it won’t be able to get a response. However, if it doesn’t throw an error, it will be able to complete.

So the way this code works is that it takes the visitor’s IP address, splits it into an array, copies it into a new array, and then reconstitutes it into the IP address string but backwards.

It then creates an instance of InetAddress and calls the getByName method passing in the created address and waits for a response. If it doesn’t get one, it does nothing. If it does get one, and the result is something that isn’t an empty string, such as 127.0.0.2, it will return and not allow whatever it is protecting to be executed.

If you are using Java the code could look like this:

try{

InetAddress inet = new InetAddress();

inet = inet.getByName(backwardsip.zen.spamhaus.org);

// this should return an IP, but it really doesn’t matter what it

// returns

String hostName = inet.getHostName();

// this is just to catch a possible error

if(hostName.length() > 0){

System.out.println(‘Visitor is dirty’);

return;

}

}catch(Exception e){

System.out.println(‘Visitor is clean’);

}

So far this is proving to be a good way to check for bad commentors. The problem is that if you are a high-traffic site, Spamhaus will want to charge you for the use of their static list. If you are a high-traffic site, you would want it anyway for performance reasons. I think the cost may be worth it though in hassle.


  • http://Website Cris Mooney

    An anomaly that might effect different users is that some name servers are banned from resolving “d.c.b.a.zen.spamhaus.org” names – presumably “firewalled out” to limit over use of “zen.spamhaus.org” (see http://www.spamhaus.org “zen -> DNSBL usage terms”).

    I suspect ColdFusion (via Java) will default to using the name service set up on your host computer – and that may be problematic and confusing for some.

    For example, commonly used DNS servers such as “4.2.2.1” can’t resolve “d.c.b.a.zen.spamhaus.org”, even for blacklisted IPs. You may use such a DNS server directly, or a DNS server you use may quietly rely on one of these indirectly (as a “forwarder”).

    You may have to find a DNS server that works, and/or set up your own DNS server to use “root servers” directly, doing its own resolution starting only with root servers that would send it directly to SPAMHAUS. Presumably your server would be within usage limits, and not get firewalled out.

  • Kasha

    Would you get inadvertently blocked yourself if you are in the Spamhaus block list? I am blocked by PBL due to my ISP putting in a block (24.57.0.0/16 is listed on the Policy Block List (PBL)) even though I have a static IP and have had no bad activity on my computer for over a year.

    Cannot remove it because of this reason: Removal of IP addresses within this range from the PBL is not allowed by the netblock owner’s policy.

    So if I use this to prevent spam will it also block me?

  • http://twitter.com/joe262_ Joe Sniderman

    Yeah pbl will include a lot of normal, well behaving end-user ranges. Its not a list of spammer IPs but rather of dynamic / end user IPs. sbl.spamhaus.org is the zone that has the spammer IPs, zen is an aggregate zone, so unless you want to block most residential users, sbl or maybe sbl-xbl would be better, no?