Sunday, December 30, 2007

Checking For Valid Email Addresses In Your CGI Forms

This weekend's obligatory code post is a little something I slapped together during a security remediation on a completely different script (it was actually written in ksh).

I actualy enjoy working with the security department on issues like this, because it gets me thinking about the potential flaws in the stuff I write and how I can improve on what I've already done. I don't think I could work as a security specialist; at least not stuck parsing scripts all day looking for minor errors (or major ones). It's not in my blood. I need to be able to get up and wander off to a server room, or someone else's desk, and give my eyes a break.

I put in a little extra functionality, at the end, since I was writing this in Perl, to actually try to resolve the domains once they managed to get past the cursory "grammar check." Hopefully you'll be able to integrate some or all of this into any CGI forms or scripts you've written or are in the process of writing.

This is not a complete CGI script; more of a function that you can use and add-in. If you do decide to do so, and use this for any forms processing, remember to add a section to strip out illegal characters. This script was written with very exacting specifications from the requestor. Check out the last part of this earlier post which goes into more detail about taking care of than end of business.

I think I covered all the bases. At this point, I probably still wouldn't want to hand this over to the security department ;) It has its flaws, for sure, but I like to put out works-in-progress if only to help kick-start some creative thinking on my (and/or your) part. In the end, it makes for better quality of work.

Best Wishes,

Creative Commons License

This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License


# 2007 - Mike Golvach -
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

use Net::DNS;

$res = new Net::DNS::Resolver;


while (<STDIN>) {
chomp; # In certain cases you may need to change this line to chop;
$_ =~ s/\r$//;
$_ =~ s/ *$//;
($cid,$email,$rest) = split(/\|/,$_,3);
$cid =~ s/ //g;
if ($email !~ /\@/) {
print "No \@ symbol in address: $cid, $email\n";
} else {
($name,$dom) = split(/\@/,$email,2);
if ($name eq "") {
print "No name on left of @ symbol: $cid, $email\n";
} elsif ($dom eq "") {
print "No domain on right of @ symbol: $cid, $email\n";
} elsif ($dom =~ /\@/) {
print "Too many @ symbols: $cid, $email\n";
} elsif ($email =~ / /) {
print "Space character in email address: $cid, $email\n";
} elsif ($dom =~ /[,]/) {
print "Comma right of @ symbol: $cid, $email\n";
} else {
$dom =~ tr/A-Z/a-z/;
$dom =~ s/\.$//;
$good = 0;
if ($dcache{$dom} != 1) {
($nm,$aliases,$addrtype,$length,@addrs) = gethostbyname("$dom");
if ($nm ne "") {
$good = 1;
} else {
@mx = mx($res, $dom);
if ($#mx >= 0) {
$good = 1;
} else {
print "Bad domin right side of @ symbol: $cid, $email\n";
if ($good) {
$dcache{$dom} = 1;
} else {
print STDOUT "$cid\|$name\@$dom\|$rest\n";

, Mike