<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Peter's Blog - Nodes for captcha</title>
    <link>http://www.petersblog.org/</link>
    <description>Nodes containing the tag captcha</description>
    <item>
      <title>Comment Spam Stats</title>
      <link>http://www.petersblog.org/node/view/1093</link>
      <description>&lt;p&gt;
I knocked up a quick python script to scan my &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt; watchdog list for comment spammers. The log covers the last week. In total there were 1250 spam attempts from 448 distinct ip addresses. 
&lt;/p&gt;
&lt;p&gt;
All these comment spams pretend to come from Windows XP, IE 6 so they cannot be filtered out by user agent.p 
&lt;/p&gt;
&lt;p&gt;
My hack to the comment module to prevent urls being submitted generates watchdog messages and this script looks for these. 
&lt;/p&gt;
&lt;p&gt;
Here is the script: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;import&lt;/span&gt; MySQLdb
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; o &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;MySQLdb.connect&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;127.0.0.1&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;me&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;secret&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;o.select_db&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;drupal_db&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt; c &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;o.cursor&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;c.execute&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;select message, hostname from watchdog&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;&lt;span class="MetaFunctionCallPy"&gt;&lt;span class="String"&gt;              where message like 'Comment:%'&lt;span class="String"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt; oBadGuys &lt;span class="Keyword"&gt;=&lt;/span&gt; {}
&lt;span class="line-numbers"&gt;  13 &lt;/span&gt; oGoodGuys &lt;span class="Keyword"&gt;=&lt;/span&gt; {}
&lt;span class="line-numbers"&gt;  14 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  15 &lt;/span&gt; &lt;span class="Keyword"&gt;while&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;:
&lt;span class="line-numbers"&gt;  16 &lt;/span&gt;     oRow &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;c.fetchone&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  17 &lt;/span&gt;     &lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Keyword"&gt;not&lt;/span&gt; oRow:
&lt;span class="line-numbers"&gt;  18 &lt;/span&gt;         &lt;span class="Keyword"&gt;break&lt;/span&gt;
&lt;span class="line-numbers"&gt;  19 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  20 &lt;/span&gt;     strMessage, strSender &lt;span class="Keyword"&gt;=&lt;/span&gt; oRow
&lt;span class="line-numbers"&gt;  21 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  22 &lt;/span&gt;     &lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;strMessage.startswith&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Comment: attempted&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;:
&lt;span class="line-numbers"&gt;  23 &lt;/span&gt;         oBadGuys[strSender] &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;oBadGuys.get&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt; strSender, &lt;span class="Constant"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="Keyword"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;
&lt;span class="line-numbers"&gt;  24 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  25 &lt;/span&gt;     &lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;strMessage.startswith&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Comment: added&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;:
&lt;span class="line-numbers"&gt;  26 &lt;/span&gt;         oGoodGuys[strSender] &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;oGoodGuys.get&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt; strSender, &lt;span class="Constant"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="Keyword"&gt;+&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;
&lt;span class="line-numbers"&gt;  27 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  28 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  29 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; Good guys manage to submit comments without problems.&lt;/span&gt;
&lt;span class="line-numbers"&gt;  30 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; Remove them from the bad guy list.&lt;/span&gt;
&lt;span class="line-numbers"&gt;  31 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  32 &lt;/span&gt; &lt;span class="Keyword"&gt;for&lt;/span&gt; strKey &lt;span class="Keyword"&gt;in&lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;oGoodGuys.keys&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;:
&lt;span class="line-numbers"&gt;  33 &lt;/span&gt;     &lt;span class="Keyword"&gt;if&lt;/span&gt; strKey &lt;span class="Keyword"&gt;in&lt;/span&gt; oBadGuys:
&lt;span class="line-numbers"&gt;  34 &lt;/span&gt;         &lt;span class="Keyword"&gt;print&lt;/span&gt; strKey &lt;span class="Keyword"&gt;+&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt; is not so bad&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  35 &lt;/span&gt;         &lt;span class="Keyword"&gt;del&lt;/span&gt; oBadGuys[strKey]
&lt;span class="line-numbers"&gt;  36 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  37 &lt;/span&gt; nTotal &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;
&lt;span class="line-numbers"&gt;  38 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  39 &lt;/span&gt; &lt;span class="Keyword"&gt;for&lt;/span&gt; strKey, nCount &lt;span class="Keyword"&gt;in&lt;/span&gt; &lt;span class="MetaFunctionCallPy"&gt;oBadGuys.items&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;:
&lt;span class="line-numbers"&gt;  40 &lt;/span&gt;     &lt;span class="Keyword"&gt;print&lt;/span&gt; strKey, nCount
&lt;span class="line-numbers"&gt;  41 &lt;/span&gt;     nTotal &lt;span class="Keyword"&gt;+=&lt;/span&gt; nCount
&lt;span class="line-numbers"&gt;  42 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  43 &lt;/span&gt; &lt;span class="Keyword"&gt;print&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="StringInterpolation"&gt;%d&lt;/span&gt; spams from &lt;span class="StringInterpolation"&gt;%d&lt;/span&gt; bad guys&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="Keyword"&gt;%&lt;/span&gt; (nTotal, &lt;span class="MetaFunctionCallPy"&gt;&lt;span class="Support"&gt;len&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;(&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;oBadGuys&lt;/span&gt;&lt;span class="MetaFunctionCallPy"&gt;)&lt;/span&gt;&lt;/span&gt;)
&lt;/pre&gt;
&lt;p&gt;
I must get on with my &lt;a href="/tag/turbogears"&gt;turbogears&lt;/a&gt; based blog so I can do more about this. Drupal logging is a bit lame: doesn't log referrer or user agent which might be useful, have to cross reference with apache logs. There is more that I can do to make it harder to suck my bandwidth but my &lt;a href="/tag/php"&gt;php&lt;/a&gt; is not strong enough and it's more fun to do in python (won't wear my $ key out). 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt; &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt; &lt;a href="/tag/python"&gt;python&lt;/a&gt; &lt;a href="/tag/spam"&gt;spam&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1093</guid>
      <category domain="http://www.technorati.com/tag">captcha</category>
      <category domain="http://www.technorati.com/tag">drupal</category>
      <category domain="http://www.technorati.com/tag">python</category>
      <category domain="http://www.technorati.com/tag">spam</category>
    </item>
    <item>
      <title>Comment spam</title>
      <link>http://www.petersblog.org/node/view/1091</link>
      <description>&lt;p&gt;
My site is being really hammerred by comment spammers today but not one has got through thanks to my policy of refusing to allow comments containing urls to be submitted (not even for moderation: I moderate all comments, I found deleting comment spam to be tedious as well as annoying). 
&lt;/p&gt;
&lt;p&gt;
It is a simple hack to the &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt; comment module but it is very effective. Ok, I could get spam without url's in but what's the point, apart from vandalism? They still go into the moderation queue and get deleted. 
&lt;/p&gt;
&lt;p&gt;
And when people do want to post url's they soon figure out how to get around the block. If they cannot do that then their comments are probably not worth consideration anyway. 
&lt;/p&gt;
&lt;p&gt;
I'd give the details of the hack here but it gives the spammers a clue. If you are interested then email me. 
&lt;/p&gt;
&lt;p&gt;
Update: following on from the vast surge in comment spam attempts (three or four a minute, 24/7), &lt;a href="/tag/statcounter"&gt;statcounter&lt;/a&gt; tells me people are searching for drupal &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt;s. I have given up on these, something about drupal states, redirects, session management or whatever stops them working reliably. The spam comment check is just part of the comment validation, there is nothing much that can go wrong with it, it is just straight if/then/else code. 
&lt;/p&gt;
&lt;p&gt;
In a way the spam check is a captcha (Completely Automated Public Turing Test to Tell Computers and Humans Apart), you can still get through if you show some smarts. It doesn't use graphics so it doesn't look cool and it doesn't shut out blind people. 
&lt;/p&gt;
&lt;p&gt;
The comment spam is coming from a range of ip addresses, maybe an array of compromised pc's (thanks Microsoft). Each 'failure' page is using some of my 10G/month bandwidth. I'll have to keep an eye out and see what kind of impact this is having. It could be even worse than inktomi slurps bots doing 100M of crawling a month and not directing anyone here through their search results. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt; &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt; &lt;a href="/tag/spam"&gt;spam&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1091</guid>
      <category domain="http://www.technorati.com/tag">captcha</category>
      <category domain="http://www.technorati.com/tag">drupal</category>
      <category domain="http://www.technorati.com/tag">spam</category>
    </item>
    <item>
      <title>Drupal Admin Block Module</title>
      <link>http://www.petersblog.org/node/view/891</link>
      <description>&lt;p&gt;
Here is an endorsement for the &lt;a href="tags/drupal"&gt;Drupal&lt;/a&gt; &lt;a href="http://drupal.org/node/19309"&gt;Admin Block Module&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
This simply adds a block to the page to tell me if there are comments ready to be moderated. This saves me from going to the administration menu to scan the log or going to administration/comments/approval queue. This isn't the biggest chore in the world but the Admin Block module has removed it for me anyway. The block only shows itself to me (as administrator) if there are comments to approve. 
&lt;/p&gt;
&lt;p&gt;
I have hacked my comment module to refuse any comment that attempts to create a link: no http, www, whatever. By refuse I mean it fails to validate, it doesn't get as far as the approval queue. This has so far proved quite effective at eliminating comment spam. Real users can read the error message and be reassured that I will edit a link to make it work when I approve the post. Any &lt;a href="tags/captcha"&gt;captcha&lt;/a&gt; haters reading, this should even work for blind people. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt; &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/891</guid>
      <category domain="http://www.technorati.com/tag">captcha</category>
      <category domain="http://www.technorati.com/tag">drupal</category>
    </item>
    <item>
      <title>captcha</title>
      <link>http://www.petersblog.org/node/view/788</link>
      <description>&lt;p&gt;
Completely Automated Public Turing Test to Tell Computers and Humans Apart. Used to stop spam-bots automatically abusing computer systems by asking a question that only a human will have the common sense or the visual processing ability to answer. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/788</guid>
      <category domain="http://www.technorati.com/tag">captcha</category>
    </item>
    <item>
      <title>Drupal Comment Captcha Fix</title>
      <link>http://www.petersblog.org/node/view/703</link>
      <description>&lt;p&gt;
I hadn't been worrying much about comment spam recently as I had been banning it successfully in my .htaccess rules as every access attempt had a spammish referrer link. 
&lt;/p&gt;
&lt;p&gt;
Once past the .htaccess block they found a bug in my &lt;a href="/node/629"&gt;comment captch mod&lt;/a&gt;: by just posting without doing a prior read of the page the session was not being set up. I've modified the &lt;a href="files/comment.module.gz"&gt;captcha code&lt;/a&gt; to cope with this. Note that this is still Drupal 4.5.1, I haven't upgraded to 4.5.2 yet. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt; &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt; &lt;a href="/tag/htaccess"&gt;htaccess&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/703</guid>
      <category domain="http://www.technorati.com/tag">captcha</category>
      <category domain="http://www.technorati.com/tag">drupal</category>
      <category domain="http://www.technorati.com/tag">htaccess</category>
    </item>
    <item>
      <title>Nofollow</title>
      <link>http://www.petersblog.org/node/view/681</link>
      <description>&lt;p&gt;
The world is waiting for my thoughts on the &lt;a href="http://www.google.com/googleblog/2005/01/preventing-comment-spam.html"&gt;nofollow tag&lt;/a&gt; the new google thing to allow it to be told when links should not be considered in page rank. 
&lt;/p&gt;
&lt;p&gt;
The idea is that links in comments can be tagged as unreliable so google will not consider them in pagerank calculations. Eventually comment spammers will give up putting links in comments and we webmasters won't have to spend our time on &lt;a href="/node/629"&gt;captchas&lt;/a&gt;, &lt;a href="http://drupal.org/node/11104"&gt;spam filters&lt;/a&gt; etc. 
&lt;/p&gt;
&lt;p&gt;
I don't like it much, it is a long term strategy that relies on ALL webmasters that allow anonymous or unverified posting to implement it and it stops honest linking in comments. 
&lt;/p&gt;
&lt;p&gt;
Commenters on my site are welcome to &lt;a href="/node/504"&gt;plug their own site&lt;/a&gt;, any spam that gets past my captcha gets deleted from the approval queue anyway. 
&lt;/p&gt;
&lt;p&gt;
No, I don't have a better solution to this problem. 
&lt;/p&gt;
&lt;p&gt;
The only good use I have found for this new tag is from &lt;a href="http://radio.weblogs.com/0001011/2005/01/18.html#a9229"&gt;scoble&lt;/a&gt; which is to use it as a way of linking when you don't want to boost the targets page rank. 
&lt;/p&gt;
&lt;p&gt;
I can use this. 
&lt;/p&gt;
&lt;p&gt;
Here goes, &lt;a rel="nofollow" href="http://www.oneandone.co.uk"&gt;one and one aka 1&amp;1&lt;/a&gt; have caused me &lt;a href="/node/675"&gt;big problems and expense&lt;/a&gt; and I urge you to &lt;a href="http://www.123-reg.co.uk"&gt;go elsewhere&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
There, revenge is sweet, best served spitefully. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt; &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt; &lt;a href="/tag/google"&gt;google&lt;/a&gt; &lt;a href="/tag/hosting"&gt;hosting&lt;/a&gt; &lt;a href="/tag/pagerank"&gt;pagerank&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/681</guid>
      <category domain="http://www.technorati.com/tag">captcha</category>
      <category domain="http://www.technorati.com/tag">drupal</category>
      <category domain="http://www.technorati.com/tag">google</category>
      <category domain="http://www.technorati.com/tag">hosting</category>
      <category domain="http://www.technorati.com/tag">pagerank</category>
    </item>
    <item>
      <title>Drupal Comment Captcha Update</title>
      <link>http://www.petersblog.org/node/view/648</link>
      <description>&lt;p&gt;
A couple of days ago a friend emailed me to tell me that he couldn't post a comment on my site as it refused the captcha characters. I hadn't had any comments for a week or two but I just put it down to apathy. I had tested it out in IE without logging in and it worked fine. Maybe the email link in my footer is not obvious enough, nobody else told me it was broken. I'll move the email link to the right. 
&lt;/p&gt;
&lt;p&gt;
When I looked into it I got it to break and I found that it was due to some strage effect where the captcha characters stored in the session information were not correctly synchronised with the captcha graphic. I fixed this by changing the code back to adding the timestamp to the captcha graphic file name. This has two effects: 
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
it forces a different catcha to each validation: if you keep posting during one session then you have to enter different captchas each time. I had tried to avoid this. 
&lt;/li&gt;
&lt;li&gt;
because the captcha graphic file name changes on each page load it makes sure that the browser downloads an up-to-date graphic file. Otherwise the browser will decide to use an old cached version of the graphic. 
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;
I guess it must be working now as I got a comment this morning. 
&lt;/p&gt;
&lt;p&gt;
I read yesterday about a &lt;a href="http://www.livejournal.com/users/bramcohen/2004/12/24/"&gt;simplified captcha system&lt;/a&gt;, basically a turing test. Just ask the poster what my name is. Easy enough to implement but if I put it in a module the question and answer ought to be configurable and our comment spamming friend may just build up a database of sites and answers. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.armadilloaerospace.com/n.x/johnc/recent%20updates/archive?news_id=290"&gt;John Carmack&lt;/a&gt; uses a similar simple approach to spam email, he asks senders to put the letters JC in the subject line and filter on that. Much nicer than asking people to edit email addresses. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt; &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/648</guid>
      <category domain="http://www.technorati.com/tag">captcha</category>
      <category domain="http://www.technorati.com/tag">drupal</category>
    </item>
    <item>
      <title>Drupal Comment Captcha mod</title>
      <link>http://www.petersblog.org/node/view/629</link>
      <description>&lt;p&gt;
Update 30/9/2005: I no longer use the Captcha. I use &lt;a href="/node/891"&gt;this&lt;/a&gt; and it works very nicely. 
&lt;/p&gt;
&lt;p&gt;
I was tired of the daily chore of deleting comment spam from my approval queue. I would consider using the &lt;a href="http://drupal.org/node/11104"&gt;spam module&lt;/a&gt;  only I wanted a solution with no administration overhead, not even training a bayesian filter. 
&lt;/p&gt;
&lt;p&gt;
I've modified the comment module from Drupal version 4.5.1 to include &lt;a href="http://en.wikipedia.org/wiki/Captcha"&gt;Captcha&lt;/a&gt; support: the user is shown a graphic containing some letters and they have to type them in. Until our comment spamming friend adds some OCR to his spamming script I should be safe. 
&lt;/p&gt;
&lt;p&gt;
My modification is based on the existing Drupal &lt;a href="http://drupal.org/project/captcha"&gt;Captcha module&lt;/a&gt; and I have been in contact with arnabdotorg, the author of this module, for approval to publish my work. I have not made any alterations to the captcha module but I have copied some of the code and it is necessary to install it in order to set up the administrative options which are also used by my modified comment module. 
&lt;/p&gt;
&lt;p&gt;
I have put my modified version of the comment module &lt;a href="files/comment.module.gz"&gt;here&lt;/a&gt;. This is only a temporary fix: the author of the Captcha module says he will be working on a proper implementation of comment captchas. 
&lt;/p&gt;
&lt;p&gt;
Notes: 
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
My modification requires anonymous users submitting comments to enter a captcha to prove they are not a spambot. 
&lt;/li&gt;
&lt;li&gt;
Users with accounts should not be asked for a captcha 
&lt;/li&gt;
&lt;li&gt;
The captcha is not checked when previewing the comment 
&lt;/li&gt;
&lt;li&gt;
One captcha is assigned per session so the user does not have to keep typing in different captcha letters (I am not sure if this is a security hole, if the captcha is guessed correctly once you will be bombarded with comment spam. However, it makes life a little easier for the users). The captcha will change if a cron session happens to wipe out the captcha files while the session is open. 
&lt;/li&gt;
&lt;li&gt;
I am not a Drupal guru and I have not considered issues like caching, whether stored session is secure etc. Hey, this is open source, peer review can help put me right. 
&lt;/li&gt;
&lt;li&gt;
The module generates a watchdog warning to mark captcha failures 
&lt;/li&gt;
&lt;li&gt;
Since this has been in place on my site (for three days) I have been seeing captcha failures regularly (4 pagefulls of warnings so far). 
&lt;/li&gt;
&lt;li&gt;
The module is running on my site (http://www.petersblog.org) so you can either break it or drop me some friendly comments. 
&lt;/li&gt;
&lt;li&gt;
I am getting as many comments now as I was getting before so real users are getting through. 
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;
Now all I need is a way to keep my referrer logs clean... 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt; &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/629</guid>
      <category domain="http://www.technorati.com/tag">captcha</category>
      <category domain="http://www.technorati.com/tag">drupal</category>
    </item>
    <item>
      <title>More on Drupal Comment Spam</title>
      <link>http://www.petersblog.org/node/view/621</link>
      <description>&lt;p&gt;
Noticed that Drupal now has a bayesian spam filter module. Nice to know but I don't really want them to get past my front door. I'd like to use a &lt;a href="http://drupal.org/project/captcha"&gt;captcha&lt;/a&gt; system where the commenter has to enter a keycode that is hard for a script to read. 
&lt;/p&gt;
&lt;p&gt;
I tried a quick hack whereby I changed the name of the POST term that submits a comment from 'Post comment' to 'Post Comment' in the hope that the spammer was running a script that just automated sending the post term. Either the submission form is being scraped for the post term or it is being done manually (unlikely). 
&lt;/p&gt;
&lt;p&gt;
If I have any ideas for simple hacks then I'll keep quiet as I don't want to give any clues away. I'll post about failures to avoid anyone else wasting their time. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/captcha"&gt;captcha&lt;/a&gt; &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/621</guid>
      <category domain="http://www.technorati.com/tag">captcha</category>
      <category domain="http://www.technorati.com/tag">drupal</category>
    </item>
  </channel>
</rss>
