Stoppa spam-bots på din sajt

Jag har spenderat lite tid för att söka efter ett bra sätt, att försvåra för spam-robotar att snappa upp emailadresser på de webbplatser jag jobbar med. Hittade lite olika lösningar som verkar mer eller mindre effektiva.

Lite olika varianter
Först tänkte jag räkna upp några av de sidor som jag besökte innan jag hittade det som kändes bäst för mig. Ett sätt som jag aldrig tänkt på innan är att använda CSS för att skydda adresserna.

Hittade också ett enkelt exempel på en javascript-variant, där man skriver ut adresserna enligt "user at example.org".

Ytterligare ett exempel finns på The Code Project. som använder en BitConverter i Asp.Net för att göra om adresserna, till något som ser ut så här: 64657266406578616D706C652E636F6D. Ett Javascript avkodar sedan strängen, så att de ser ut som vanligt för användaren. Eftersom de flesta spam-bots inte kör javascript så kan de inte se att det är en emailadress.

Använda en HttpModule för att stoppa spam
Den metod som jag valde att använda hittade jag på Webpronews.com. Den gör om emailadresserna till hexadecimala tecken. Och den gör det på ett väldigt smart sätt eftersom den blandar de hexadecimala tecknen med vanliga, enligt en slumpvis algoritm. I en webbläsare ser adresserna helt vanliga ut, men spamrobotarna kommer få problem. Det fina med att använda en HttpModule är ju att ma inte behöver koda om alla sidor på webbplatsen. Modulen tar hand om detta och applicerar det över hela sajten. För att vara ännu säkrare kan man även kombinera denna teknik med en javascript-variant.

Så här lägger man till en referens till modulen i web.config:

<httpModules>
<add type="EmailSpamModule" name="EmailSpamModule" />
</httpModules>

Själva koden för modulen läggs i App_Code och ser ut så här:

#region Using

using System;
using System.IO;
using System.Web;
using System.Text;
using System.Text.RegularExpressions;

#endregion

/// <summary>
/// Removes whitespace from the webpage.
/// </summary>
public class EmailSpamModule : IHttpModule
{

#region IHttpModule Members

void IHttpModule.Dispose()
{
// Nothing to dispose;
}

void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}

#endregion

void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
if (app.Request.RawUrl.Contains(".aspx"))
{
app.Response.Filter = new SpamFilter(app.Response.Filter);
}
}

#region Stream filter

private class SpamFilter : Stream
{

public SpamFilter(Stream sink)
{
_sink = sink;
}

private Stream _sink;

#region Properites

public override bool CanRead
{
get { return true; }
}

public override bool CanSeek
{
get { return true; }
}

public override bool CanWrite
{
get { return true; }
}

public override void Flush()
{
_sink.Flush();
}

public override long Length
{
get { return 0; }
}

private long _position;
public override long Position
{
get { return _position; }
set { _position = value; }
}

#endregion

#region Methods

public override int Read(byte[] buffer, int offset, int count)
{
return _sink.Read(buffer, offset, count);
}

public override long Seek(long offset, SeekOrigin origin)
{
return _sink.Seek(offset, origin);
}

public override void SetLength(long value)
{
_sink.SetLength(value);
}

public override void Close()
{
_sink.Close();
}

public override void Write(byte[] buffer, int offset, int count)
{
byte[] data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
string html = System.Text.Encoding.Default.GetString(buffer);

html = EncodeEmails(html);

byte[] outdata = System.Text.Encoding.Default.GetBytes(html);
_sink.Write(outdata, 0, outdata.GetLength(0));
}

private static string EncodeEmails( string html)
{
foreach (Match match in _Regex.Matches(html))
{
html = html.Replace(match.Value, Encode(match.Value));
}
return html;
}

private static Regex _Regex = new Regex("(mailto:|)(\\w+[a-zA-Z0-9.-_]*)@(\\w+).(\\w+)");
private static Random _Random = new Random();

private static string Encode(string value)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < value.Length; i++)
{
if (_Random.Next(2) == 1)
sb.AppendFormat("&#{0};", Convert.ToInt32(value[i]));
else
sb.Append(value[i]);
}

return sb.ToString();
}

#endregion

}

#endregion

}

Jag hoppas att skaparen av detta kod tycker det är okej att jag publicerar den.
In english: I hope that the creator of this code approves that I republish it. If not, just contact me and I will remove it. I also found it here and here.

En prestandavarning
När jag provade på ett riktigt långt html-dokument så fick jag lite oväntade problem. Vet inte riktigt vad det beror på. På kortare sidor fungerar modulen bra.

En bete för bots
Till sist tänkte jag använda metoden för att lägga ut ett bete för spam-botsen. Följande adress har jag skapat endast för denna sidan och jag kommer inte lägga ut den någon annanstans. Får jag ett spam till den adressen så vet jag att en bot har överlistat systemet.

spammeifyoucan@codeodyssey.com

I koden bakom ser denna adress ut som följer, svårt för till och med en spam-bot att fatta.

s&#112;&#97;&#109;m&#101;if&#121;oucan@c&#111;&#100;&#101;o&#100;y&#115;&#115;ey.&#99;o&#109;

By Jesper Lind

Världsmästerskap i SEO-optimering

Nu är det stor tävling i SEO på gång, som anordnas av Eastpoint. Skulle vara kul att delta men kommer nog aldrig orka satsa fullt ut på en sån här grej. Och det lär bli väldigt hårt motstånd från proffsen i sökoptimerings-branschen. Får se, kanske ställer upp för skojs skull.

Priserna är riktigt bra och man kan bland annat vinna en bil, en kryssning till Karibien och en plastma-tv. Nyckelorden kommer att tillkännages den 15:de januari kl 13:00. Se "Rocky-style" promo-video

By Jesper Lind

Prototyp av 3D-skrivbord

http://www.codeodyssey.se/upload/resource/blog/3d-pdf.jpg

BumpTop - som är i utvecklingsfasen, ser rätt coolt ut. Man kan ta dokument och slänga runt dem på ett tredimensionellt skrivbord. När jag ser mitt oftast överfulla skrivbord på datorn, så längtar jag efter en sån här lösning.

Se video på YouTube

By Jesper Lind

Stavnings- och grammatiktips

Amatörskribent som man själv är så kan det behövas lite hjälpmedel för att skriva bättre och korrekt svenska. Jag är medveten om att mina blogg-inlägg ofta innehåller en hel del felaktigheter men jag jobbar på att bli en bättre skribent. Tänkte här dela med mig av några användbara tips av hjälpmedel som jag brukar använda.

Rättstavningen i Firefox som lanserades när version 2 släpptes är helt fantastiskt bra när man bloggar, förstår inte hur jag har kunnat klara mig utan det innan. Annars är ju Skolverkets lexikon en klassiker som jag använt flitigt genom åren. Söker man synonymer till ord är synonymer.se en bra sida.

Mediesprak.fi bjuder på en hel del bra tips för hur man använder stor och liten bokstav, skiljetecken, förkortningar m.m.

Researcher.se har också sammanställt lite nyttiga länkar om hur man skriver bättre texter.

By Jesper Lind

Pagebull - sökresultat som bilder

Jag håller med internetbrus.com att tjänsten Pagebull.com är en riktigt intressant söktjänst. Tycker att det visuella presentationen fungerar riktigt bra.

Det känns skönt att se webbplatsen, innan man klickar in en länk och redan då avgöra ifall webbplatsen ser ut att vara värt ett besök. Detta är nog något vi kommer få se mer av i framtiden. Pagebull använder sig av Yahoo! Web Services.

By Jesper Lind

Klass-fil som genererar lösenord

Här visar jag ett exempel på en bra klass för att generera lösenord. Lösenorden blir 10 tecken långa och skapas av endast tecknen a-z, A-Z, 0-9.

Det är inte jag som utspungligen skrev den men har använt den så länge att jag glömt bort vart den kommer från. Om någon känner igen koden, hör gärna av er så ska jag skriva en referens till skaparen.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Text;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/// <summary>
/// Summary description for PasswordGenerator
/// </summary>


public class PasswordGenerator : Page
{
private char[] characterArray;
private Int32 passwordLength = 10;
Random randNum = new Random();

public PasswordGenerator()
{
characterArray = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray();
}

private char GetRandomCharacter()
{
return this.characterArray[(int)((this.characterArray.GetUpperBound(0) + 1) * randNum.NextDouble())];
}

public string Generate()
{
StringBuilder sb = new StringBuilder();
sb.Capacity = passwordLength;
for (int count = 0; count <= passwordLength - 1; count++)
{
sb.Append(GetRandomCharacter());
}
if ((sb != null))
{
return sb.ToString();
}
return string.Empty;
}
}

By Jesper Lind

Ny webbtjänst konverterar dina filer

De nya webbtjänsterna duggar tätare än regnskurarna här i Göteborg. Nu släpps Zamzar.com som är en tjänst som erbjuder gratis konvertering för en mängd olika format. Tänkte göra en lista på vilka format som stöds men den skulle bli för lång...

Detta är ju perfekt när man behöver just det där speciella formatet, men inte har något eget program som kan hantera det. Återigen ett bevis på att de smarta tjänsterna flyttar ut från våra datorer och läggs på nätet.

Tjänsten fungerar så att man laddar upp en orginalfil som kan vara upp till 100 MB stor. När konverteringen är klar får man ett email med en länk till den nya konverterade filen. Länken fungerar i 24 timmar och under den tiden kan du ladda hem den, eller kanske skicka vidare till någon annan. Via: Webbsnack

By Jesper Lind