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:
- Converts literal " " character sequences to newlines
- Adds measures against form spam
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:
- TFmail-1.38-bscott1.diff - Diff against TFMail version 1.38
- PKZip archive containing
- Modified TFMail, ready-to-run
- Above-mentioned diff
- Sample spam rejection notification templates
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.)
Spam hits everything, including HTML forms. Most of it comes from fairly dumb robots (bots), so fairly simple countermeasures can be effective.
- Config file directive: reject_html
- Syntax: Field names, separated by commas
- Semantics: If any listed field is submitted containing HTML, the submission is rejected as spam.
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.)
- Config file directive: trapfield
- Syntax: Field names, separated by commas
- Semantics: If any listed field is submitted non-empty, the submission is rejected as spam.
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
- Config file directive: spam_template
- Syntax: Template base file name
- Semantics: As for other TFMail templates
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
- Config file directive: spam_redirect
- Syntax: URL
- Semantics: As for other TFMail redirect directives
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.
- Config file directive: spamlog
- Syntax: Base name of log file
- Semantics: File to log info about submissions rejected as spam. No logging if not defined.
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.)