A Question Regarding a CGI script

shockme on 2003-12-09T23:01:06

Consider the following script:

#!/usr/local/bin/perl
use strict;
use CGI qw(param);

$user_name = param(UserName);
$email_addy = param(EmailAddy);
$comments = param(Comments);

open(SENDMAIL, "| sendmail -oi -t") or die "Can't fork for sendmail: $!\n";
print SENDMAIL <<EOF;
From: $email_addy
To: joe\@exitwound.org
Subject: Message from $user_name

$user_name ($email_addy) has sent you the following:

-----------------------------------------

$comments

-----------------------------------------

EOF
save_parameters(*SENDMAIL);
close(SENDMAIL);

Other than flooding Joe's inbox, can you think of any way that this script could be abused? More specifically, is it possible to abuse this script to send email to someone other than Joe?



Posted from exitwound.org, comment here.


Drive-by email

dws on 2003-12-09T23:33:33

You'll want to screen $email_addy to prevent someone from passing in, say "foo@bar\nCc: somebodyelse@example.com".

Re:Drive-by email

shockme on 2003-12-10T00:28:54

When I passed it that from a simple form, it emailed me the following:
Test Name (steveNOSPAM@exitwound.org\nCc:stephenNOSPAM@hsc.edu) has sent you the following:
It only sent one email, and that was to the address hardcoded in the To: field in the script. I never received an email at the Cc: address.

The email header shows:

From: "steveNOSPAM@exitwound.orgnCc:stephenNOSPAM" <@ttuhsc.edu>

which is weird, but still unsuccessful.

Re:Drive-by email

dws on 2003-12-10T00:55:38

Looks like you're losing the newline. Are you sure you're passing \n (%0A%0D)?

Re:Drive-by email

shockme on 2003-12-10T01:10:37

Here is a cut-and-paste of what I sent:

steveNOSPAM@exitwound.org%0A%0DCc:shockNOSPAM@exitwound.org

and

steveNOSPAM@exitwound.org\nCc:shockNOSPAM@exitwound.org

Both resulted in one email being sent to the hardcoded To: address, with nothing being received as a copy. And both resulted in goofed headers as previously described.

What am I missing here? I agree with you that not checking $email_addy should be abusable, but I don't seem to be able to replicate it.

Re:Drive-by email

dws on 2003-12-10T06:11:15

My bad. Injecting %0A is sufficient.

Re:Drive-by email

shockme on 2003-12-11T00:40:10

Pasting

steveNOSPAM@exitwound.org%0ACc:shockNOSPAM@exitwound.org

results in the same thing ... Jeez. What am I missing here? This script may be insecure, but I'll be damned if I can prove it.

Re:Drive-by email

dws on 2003-12-11T17:30:27

Here's a simple test case. $to simulates a query parameter that someone has injected a %0A into. With suitable substitutions for email addresses, I get an email to each address.
use CGI;

my $to = CGI::unescape("a\@example.com%0ACc: b\@example.com");

open(SENDMAIL, "| sendmail -oi -t") or die "sendmail: $!\n";
print SENDMAIL <<EOF;
From: test <you\@example.com>
To: $to
Subject: Automagic message

Gotcha
EOF
close(SENDMAIL);

personally I avoid directly calling sendmail

WebDragon on 2003-12-11T23:14:04

...preferring to use the Mail::Mailer interface. You might look at that as an alternative.

Re:personally I avoid directly calling sendmail

shockme on 2003-12-12T02:01:13

I'm with you. That would have cleaned the script up quite a bit.

Unfortunately, in this situation, the developer has no control over the installed modules. He has to live with what he has, and in this case has to follow the FAQ on sending mail.

dws pretty much hit it on the head with the inadequate (i.e., no) untainting/validation of the input.

But yeah, if the situation was different, I'd definitely go with modules.