If a CGI (including Perl, PHP etc) script on your site is actively causing security problems for our servers, or otherwise endangering the availability and effectiveness of the service for our customers, then we may have to disable the problem script. We will usually then ask you to fix the script (e.g. close the security holes) before it is re-enabled.

Spam Relaying

The most common form of security problem that we encounter with our customers' CGI scripts is spam relaying. This means that spammers have found that it is possible to use your CGI script to send spam.

An ideal vulnerable CGI script, from a spammer's point of view, is one which allows them to generate email with aribtrary content of their choice: their choice of "From" address, "To", "Cc" and "Bcc" addresses, their choice of subject, and their choice of message body. Less ideal (from the spammer's point of view) would be one which allows only partial control of these things: for example, maybe they could set the "From" and "To" headers, but not the subject, and maybe they could only partially control the body of the message.

Your goal is to ensure that your CGI script is capable of doing what you need it to (e.g. emailing feedback to you), whilst also ensuring that is incapable of being used for any other purpose.

The most common causes of spam-relaying CGI errors are reliance on hidden form fields, and header injection.

Hidden Form Fields

Often a site will use an HTML page containing a "send email" form; the form will often have hidden fields, used to control things such as the subject of the message, or the recipients. For example:

  <input type="hidden" name="subject" value="Web site feedback">
  <input type="hidden" name="recipients" value="feedback@example.com">

The form will then submit its contents to the CGI script, which then receives the hidden fields (and the visible ones) and acts on them. (For example, by sending an email with subject "Web site feedback" to feedback@example.com).

Without any further controls, this is a recipe for disaster. Spammers will bypass your HTML form and submit data straight to the CGI script, substituting their preferred subject, recipient, and so forth. Hey presto, instant spam relay.

Header Injection

This one seems to most commonly affect PHP scripts for some reason, although there is nothing PHP-specific about this attack.

A Typical Setup

What usually happens is something like this:

For example, a "legitimate" use of this script may have

$visitor_email_address = "web-site-visitor@example.net"
$visitor_message = "Hello,

Great site!  Where can I find out more about your company?"

Note specifically that $visitor_email_address is a "single line" string, but $visitor_message is a "multi line" string (it contains "newline" characters).

A Typical Attack

Now, consider what happens when a spammer (again, bypassing your HTML form and submitting the data straight to the CGI script) submits the following data:

$visitor_email_address = "freepillz@pharmacy.biz
To: Undisclosed recipients <>
Bcc: alice@aol.com, bob@aol.com, charles@aol.com, diane@aol.com
Subject: Enhance parts of your anatomy without a prescription

We have cheap meds available now, no doctor required!
etc. etc.

(large number of blank lines here)
.
"
"
$visitor_message = ""

Again, your CGI script builds up the message as follows:

From: $visitor_email_address
To: feedback@example.com
Subject: Web site feedback

$visitor_message

which results in the following message:

From: freepillz@pharmacy.biz
To: Undisclosed recipients <>
Bcc: alice@aol.com, bob@aol.com, charles@aol.com, diane@aol.com
Subject: Enhance parts of your anatomy without a prescription

We have cheap meds available now, no doctor required!
etc. etc.

(large number of blank lines here)
.

To: feedback@example.com
Subject: Web site feedback


So the spammer has managed to send spam via your web site, but with his choice of "From", "To", "Bcc" and "Subject" headers, and his choice of message. In fact the only part he couldn't control, in this example, is that right at the bottom of the message, after a load of blank lines that he inserted, were the "To" and "Subject" lines of your intended message.

Cause and Defence

The spammer has managed this by adding newline characters to a form field where you weren't expecting any, namely (in this example) in the "visitor_email_address" field. Newlines aren't the only "unsafe" character though. The best defence against this form of attack is to validate all data which you receive from the form as strongly as possible before it is turned into an email (or do anything else with it, in fact).

For example, if you're expecting an email address, it's reasonable to insist that it only contain the following characters: A-Za-z0-9@_.-

Another good defence is to minimise as much as possible the ways in which the header of the email can be varied. For example, when someone sends you feedback via your web site, do you really need their email address in the "From" header, or would it be acceptable to have it in the body of the message instead? Granted, it makes it less convenient if you want to reply to their feedback (because you won't just be able to hit "Reply"), but the advantage is a far more secure CGI script.

So for example you could change your message template from this:

From: $visitor_email_address
To: feedback@example.com
Subject: Web site feedback

$visitor_message

to this:

From: "web server" <>
To: feedback@example.com
Subject: Web site feedback

The following feedback was submitted by $visitor_email_address

$visitor_message

CGI Security (last edited 2006-05-15 10:31:07 by DaveEvans)