Modified TFMail

About TFMail

TFMail is a CGI script maintained by the London Perl Mongers which acts as an HTML-form-to-email-gateway. The HTML form is submitted via the CGI script; CGI script emails result to someone. It is more flexible than the classic "FormMail", and more secure than many common "FormMail" scripts. It has a templating system, supports multiple configuration files, and... oh, just go visit the site .

About my modifications

I use TFMail, on this site and elsewhere. In the course of that, I have made some very simple modifications:

More detail below. Others have expressed interest, so here's a page about it.

Help and support

To be explicit: The London Perl Mongers, and/or the TFMail user community, generally do not support modified scripts. So if you have troubled with something unrelated to my modifications, please try a "vanilla" TFMail first. If the problem is with my modifications, at the very least, say so up-front in any problem reports.

Also to be explicit: I am not in the business of providing general TFMail support for free. If the problem is not with my modifications, please seek help in an appropriate forum, such as the nms-cgi-support list.

If you have a bug report or other feedback on my modifications, though, please let me know.

Obtaining the patch

I posted my patch to the nms-cgi-devel list, but got no response. Not even a "That's not what we're looking for". I dunno if that list is just dead or what.

So on this page I offer for download:


We would sometimes get form submissions containing the literal string "
" (without the quotes) (10 characters). That's obviously an HTML escape sequence for CR+LF, but what was that doing in the email? I have no idea*, but the customer didn't like it. So I added a quick pattern replacement that turns that sequence into a newline.

(* I actually do have an idea: Testing revealed that, when submitting a multi-line response (TEXTAREA) via POST, Firefox and MSIE seem to encode things differently. Whether one or the other or both or neither is "correct", I didn't bother researching. It needed to be compensated for.)

Form spam

Spam hits everything, including HTML forms. Most of it comes from fairly dumb robots (bots), so fairly simple countermeasures can be effective.

Reject HTML

I noticed that most of these submissions included something like a URL in an HTML anchor tag. So I added a directive which allows you to declare field(s) to never contain HTML. If they do, the submission is rejected as spam.

In the current implementation, it doesn't actually reject HTML -- it just looks for the very simple pattern most spam seems to have. This can be improved to actually reject all HTML, if needed. (And if this patch gains popularity, that will doubtless be needed.)

Trap fields

I also added support for trap fields, which are form fields which should never contain any content. Include a trap field in your HTML form, clearly marked (to the human reader) to be left empty, and hidden with CSS. Bots don't read English, and most don't parse CSS. So the user will likely never see the field, and if they do, they will know to leave it empty. Bots will stuff it full of crap, identifying them as unwanted.


Rejection with template

When the script decides to reject a submission as spam, it processes the designated spam template and sends that to the user. In addition to all the usual template fields that would be available on a successful submission, there is an additional "spam_field" collection, which works like the "input_field" collection. You can thus FOREACH over the fields identified as spam.

I recommend using a vague message for normal use. You don't want to tell the spammers exactly what they need to attack. A example of one such template is included as "spam_vague.trt" in the ZIP file. You will need to change the phone numbers.

For testing/diagnostic purposes, it may useful to have an exact listing of which fields were rejected. The "spam_diag.trt" in the ZIP file is an example. Again, I do not recommend being that specific in regular use.

Rejection with redirect

This is an alternative to "spam_template". When the script decides to reject a submission as spam, it issues an HTTP redirect to the given URL.


It may be useful to be able to see what is being rejected as spam, especially during initial setup, or if you have trouble reports. This directive will cause all rejected submissions to be logged to the specified file. Just specify the base name for the file. The extension (TFMail LOGFILE_EXT) will be automatically added. It will be written to the TFMail LOGFILE_ROOT directory.

Log format is one entry per nominal line, and includes date, time, HTTP client IP address, HTTP VIA header, HTTP User Agent header, and form fields. In that order. Things the client submits are wrapped in angle brackets (<>). Note that if submission includes newlines or other nasty characters, they will be included in the log file, so don't blindly trust it or throw it at a simple parser. (This should perhaps be changed.)

Go to my home page
Last modified: $Date: 2022/12/10 02:43:04 $ (YYYY/MM/DD UTC)