Page 1 of 2

str_replace not working

Posted: Mon May 08, 2006 5:41 pm
by andym01480
Done some code for someone and used the following to clean input (with more added rude words).

Code: Select all

//$naughtybits is all the stuff you don't want appearing in an email
$naughtybits=array('\\','+',';','\n','\r','%0A','Content-Type:','MIME-Version:','Content-Transfer-Encoding:','bcc:','cc:','crap');

//Grab form data and clean
$yourname=str_replace($naughtybits,'',$_POST['yourname']);

It works fine on my home XXAMP setup (5.1.1) and on my hosts server (4.4.1), but the person I did it for says it doesn't work on their setup.

I've checked the php manual & looked in phpinfo on my setups but can't see any reason why it wouldn't work. Any ideas?
And have I missed any naughtybits that could be used for email injection or sql injection for that matter?

Posted: Mon May 08, 2006 5:44 pm
by wtf
escape characters will not work with single quotes i think

Posted: Mon May 08, 2006 5:59 pm
by andym01480
Mmmm. Surely the single quotes means that the \\ is treated as \\ rather than an escaped \?

Just tried

Code: Select all

$yourname="\\escaped\n\rcrap stripped out";
//$naughtybits is all the stuff you don't want appearing in an email 
$naughtybits=array('\\','+',';','\n','\r','%0A','Content-Type:','MIME-Version:','Content-Transfer-Encoding:','bcc:','cc:','crap'); 

//Grab form data and clean 
$yourname=str_replace($naughtybits,'',$yourname);

echo $yourname;
which outputted

Code: Select all

escaped stripped out
Help! Why does it work on my servers and not on someone elses?

Posted: Mon May 08, 2006 6:04 pm
by feyd
double-backslash in a single quote string is an escaped backslash, just like the test string you are using has an escaped backslash leading it.

Posted: Mon May 08, 2006 6:15 pm
by andym01480
So are you saying that it's not working on my setup either? It's late and now I'm confused. (This thread should probably be in PHP-Security.)

The bottom line is - am I deluded into thinking I have protected myself from email injection with that code snippet? If so how can it be improved?

Posted: Mon May 08, 2006 6:25 pm
by Christopher
I believe in single quotes that only '\\' and '\'' work for escaping, so you need to do "\n" and "\r".

Posted: Mon May 08, 2006 6:28 pm
by s.dot
aborint is correct. i recently ran into the same problem. can speak from experience =]

Posted: Tue May 09, 2006 1:12 am
by RobertGonzalez
I second the motion...

Posted: Tue May 09, 2006 1:32 am
by dibyendrah
Couldn't figure out what is the problem in this thread :roll:
Any code sample will clear the solution rather than just a comment I guess !

Dibyendra

Posted: Wed May 10, 2006 2:31 pm
by andym01480
I'm back!

What would strip out an email injection attempt then please?

Posted: Wed May 10, 2006 3:55 pm
by RobertGonzalez
What do you mean by 'email injection attempt'?

Posted: Wed May 10, 2006 4:05 pm
by andym01480
Sorry for the obviously not great question!

I thought that "email injection" refered to when a form user added email headers to a form input for a field like email address. Thus using a form to send spam.

From what i understand something like

Code: Select all

a@b.co.uk \r\n cc: b@b.co.uk
would mean that the send email address was injected by the form user

I was trying to crack the problem by str_replace. Got it stripping out naughties like \r, \n %0A, %0D, cc:,bcc: etc but then found an email using mail() would fail to send the stripped result anyway

Code: Select all

a@b.co.uk b@b.co.uk
I have googled and searched the regex section of this excellent site and found
http://www.iamcal.com/publish/articles/ ... ing_email/ which checks that a valid email address was entered, so I am going to code the form process to reject input that isn't a valid email.

If other form fields make up the body of an email sent when processed are they they in danger of having header type stuff added?

Posted: Wed May 10, 2006 4:06 pm
by Maugrim_The_Reaper
Just check for illegal characters, error, tell the user to spam someone else (with an XHTML 1.0 compliant page of course) et voila!

What you are doing is "fixing" corrupt user input. It's a bad practice since it allows the possibility of someone evading your filtering logic. Don't do this. Just check if the data is valid or not. If not, make the user fix it - it's their request and their responsibility. If they insist on passing you bad data, record their details and ban their IP for a set period. You can also add a forced delay between all requests to the form from the same IP or source - make their bot progress a torture should they use one...

Again, don't fix bad input.

Posted: Wed May 10, 2006 4:10 pm
by RobertGonzalez
If you are expecting a single email address, regex the input field for a single email address compatibility. If it passes, you are golden. If it doesn't, error the script out and send the user a message. I like Maugrim's way of putting it...
Maugrim_The_Reaper wrote:tell the user to spam someone else (with an XHTML 1.0 compliant page of course)

Posted: Wed May 10, 2006 4:15 pm
by andym01480
Thanks! Am implementing advice!

The other form fields get put into a table that makes up the variable of $body It's an html formatted email.

Code: Select all

mail($email,$subject,$body,$headers);
If headers were placed in $body are they ignored by the function?