Forcing Comment Previews
I’m only about 6 months behind in writing this up.
Back when I first implemented Comment Validation, I relied on a very simple bit of social engineering to ensure that comments got run through the Validator before posting. Near the <textarea>
where you enter/edit your comment, there’s a PREVIEW button, but no POST button. The POST button only appears on the Comment Preview form when you’ve previewed the comment, and it has successfully Validated.
If you then scroll down and edit the comment, you are supposed to click on PREVIEW again. But if you actually look at the code I suggested for the Comment Preview page, you quickly realize that nothing prevents you from scrolling back up and clicking on POST instead. I ran with this system for 7 months without a single invalid comment being posted. But just because nobody’s yet come around and rattled the door handle, there is no reason to leave the backdoor perpetually unlocked.
Besides, spambots and crapflooding scripts bypass the comment form entirely, and POST directly to the comment CGI script. They’re immune to social engineering. A better solution was called for.
So, 6 months ago, I created a plugin to solve the problem. Introducing MTHash.
Installation is easy:
- The plugin’s only prerequisite is the
Digest::SHA1
Perl module. - Put the plugin in your
plugins
directory. - Create a text file called
salt.txt
with some random gibberish in it, and place that, too, in yourplugins
directory.
The plugin offers two new MT Container Tags
<MTSHA1Hash>...</MTSHA1Hash>
- Replaces its contents by an SHA1 hash of the contents.
<MTSHA1SaltHash>...</MTSHA1SaltHash>
- Replaces its contents by an SHA1 hash of the contents salted with the aforementioned
salt.txt
file’s contents. Unlike the previous one, this can’t be pre-computed without access to thesalt.txt
file.
OK, so how do we use it?
- In the Comment Preview form, we add a hidden form field
(note that the MT tags in green, for the subject and text-filter of the comment, are special to my setup; you might need to omit them both here and below).<input type="hidden" name="validated" value="<MTSHA1SaltHash><MTCommentPreviewBody convert_breaks='0' sanitize='0'><$MTEntryID$><MTCommentPreviewIP><$MTCommentPreviewAuthor$><$MTCommentPreviewEmail$><$MTCommentPreviewURL$><$MTCommentPreviewSubject$><$MTCommentPreviewTextFilter$></MTSHA1SaltHash>" />
- Then we modify
lib/MT/App/Comments.pm
--- lib/MT/App/Comments.pm.orig Thu Jul 1 15:29:58 2004 +++ lib/MT/App/Comments.pm Sun Aug 1 23:34:52 2004 @@ -229,6 +277,24 @@ if (!$q->param('text')) { return $app->handle_error($app->translate("Comment text is required.")); } + require Digest::SHA1; + my $sha1 = Digest::SHA1->new; + + $sha1->add($q->param('text') . $q->param('entry_id') . $app->remote_ip + . $q->param('author') . $q->param('email') . $q->param('url') . $q->param('subject') . $q->param('convert_breaks') ); + my $salt_file = MT::ConfigMgr->instance->PluginPath .'/salt.txt'; + my $FH; + open($FH, $salt_file) or die "cannot open file <$salt_file> ($!)"; + $sha1->addfile($FH); + close $FH; + + my $digest = $sha1->b64digest . "="; + + if ($q->param('validated') ne $digest) { + return $app->handle_error($app->translate( + "Please preview your modified entry before posting it.")); + } + my ($comment, $commenter) = _make_comment($app, $entry); if (!$blog->allow_unreg_comments) { if (!$commenter) {
That’s it! If you modify your comment, now you must preview it again before posting. [Revised (8/1/2004) to be even more bulletproof. Revised (9/1/2004) for MT-3.1 compatibility.]
As a side benefit, spambots, which post directly to the Comment CGI script don’t work any more. Some of my friends who’ve been using this technique (without the Validation part) tell me it works wonders against spambots.
I wouldn’t know; I don’t get comment spam anymore (so far, only 15 spam comments in over 8 months).
Posted by distler at June 16, 2004 9:59 AM
Re: Forcing Comment Previews
Thanks a lot for this work. I am going to implement it today, since I can’t use MT-Blacklist anymore now that I use MT3.0D.
(I have to admid that I tried it out by modifying my post in the preview window and clicking the Post button, but it works flawlessly)