Vulnerable mail script?

software development

#1

[color=#00CC00]I need some help with a vulnerable mail script. I got a message from Dreamhost saying they’d disabled sendmail for my user because they were getting flak from AOL and they’ve surmised that I have a vulnerable mail script in there.

Wonmdering if someone can point out the hole (I don’t script so I’m clueless, friend did this for me a year or so ago)

The suspicious script:[/color]

[code]<?php
ob_start();
$addresses = array();

$addresses[1] = ‘name@domina.net’;
$addresses[2] = ‘person@domain.com’;

$names = array();

$names[1] = ‘Mr Name - President’;
$names[2] = ‘Ms Person - Secretary/Treasurer’;

if ($sendmail) {

$to = $addresses[$email_num];
$subject = ‘website email’;
$mailheaders = “From: $name <$email>”;
$mailheaders .= “Reply-To: $email”;

$msg = stripslashes($msg);

$result = mail($to, $subject, $msg, $mailheaders);

if ($result) {
header (“Location: http://”.$_SERVER[‘HTTP_HOST’]."/contact/thanks.html");
exit;
} else {
print(“

There’s been a problem sending the mail. Close this window and try again. If the problem persists email webmaster at domain dot com

\n”);
}
exit();
}
ob_end_flush();
?> spammer!

E mailing: <?= $names[$email_num]; ?>

your name:

your email:

your message:

[/code][color=#00CC00]A link to this script that passes the number looks like:[/color]

<a href="/contact/mail_form.php?email_num=1">Email Mr Name</a> [color=#00CC00]your help is appreciated![/color]

[color=#0000CC]jason[/color]


#2

I’m not into PHP coding myself, so I’m probably missing something at the moment.

But one thing that I see is this:

$addresses = array(); $addresses[1] = 'name@domina.net'; $addresses[2] = 'person@domain.com'; $to = $addresses[$email_num];The script does not verify that $email_num is a number, or that it is either a 1 or a 2.

$mailheaders = "From: $name <$email>"; $mailheaders .= "Reply-To: $email";The script does not insert a linebreak between the From and Reply-To headers. The hole might very well be here - the script does not check the $name or $email values at all, allowing one to exploit the script by inserting their own headers such as Cc or Bcc.

When coding scripts that accept any type of input at all from untrusted sources such as an web site visitor, it is best to figure out exactly what type of input one expects and code the script to only accept that type of input. One should never assume that the input recieved is always valid and/or not an attempt to exploit a flaw.

Secondly, you probably would have been aware of the problem before it got out of hand if the script was logging its actions somehow. Obviously it should appear in the web server log files, but there is nothing stopping one from writing a script that maintains a log file of its own, including the logging the headers for security auditing.

:cool: Perl / MySQL / HTML+CSS


#3

thanks alot man, gives us a starting point!

I suspected (clueless as I am :p) that since I saw no checks that I could append an address in place of the number in the url and submit the form so I tried that… it worked.

Then I reported the behavior and problem to the friend that wrote the script a day or 2 later and that day neither of us could reproduce the behavior! I was wondering if I had actually only dreamed the tests :slight_smile: or if sendmail was globally disabled at the time of this second test or somesuch, very odd anyhow. So I posted here, I appreciate you looking at it and helping out!

[color=#0000CC]jason[/color]


#4

Atropos7

Could you expand on this a bit? When you say a linebreak between the headers do you mean like:

$mailheaders = “From: $name <$email>\n”;
$mailheaders .= “Reply-To: $email\n”;

With regard to the Cc anb Bcc, is there a best practice when checking for these? Should I just search the email address the user entered for Cc and Bcc and reject it if found?

Thanks


#5

[quote]Could you expand on this a bit? When you say a linebreak between the headers do you mean like:

$mailheaders = “From: $name <$email>\n”;
$mailheaders .= “Reply-To: $email\n”;[/quote]
Read the PHP documentation on the mail() function.

Read the specifications on formatting message headers and e-mail addresses and write code that understands them and the possible exploits.

That would be silly. What about the other message headers? What if cc was part of a name, like Rebecca? It’s like a recipe. You have a list of ingredients. You have to make sure only those ingredients get put in, in the right order.

:cool: Perl / MySQL / HTML+CSS


#6

I went back to the trusty nms formmail and just used the names array to match up to the address array in formmail, solid. Didn’t even have to change all the links to the mailform page. I appreciate the help.

[color=#0000CC]jason[/color]


#7

All php scripts that use mail() or mysql are vulnerable to code injections if the information that a user inputs in a form is not check carefully for abnormalities

for mail() you should check the input of the user for things like

Content-Type:
MIME-Version:
Content-Transfer-Encoding:
bcc:
cc:

I had a problem with one of my forms and the script was used to mass mail a lot of people because it was vulnerable to header injections on the mail() form.

Now i have a stronger form validation. It checks all input fields that are sent thru including radio buttons and checkboxes.

It is also recomended to create a simple script to check the lenght of the input on each field and anything longer that expected should make the script die or exit.

here’s a page that discusses code injection in more detail.

http://securephp.damonkohler.com/index.php/Email_Injection