preventing header injection

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

oboedrew
Forum Commoner
Posts: 78
Joined: Fri Feb 20, 2009 1:17 pm

preventing header injection

Post by oboedrew »

I'm reading up on the topic of header injection prevention, since I'm about to put a contact form on my website, and I've seen a number of articles recommending that the strings "content-type:" and "multipart/mixed" both be stripped from form input. But if the former is prohibited, isn't prohibiting the latter overkill? If somebody tries to insert "content-type: multipart/mixed," forbidding "content-type:" seems adequate. Or is there some other devious use of "multipart/mixed?"

Thanks,
Drew
User avatar
jaoudestudios
DevNet Resident
Posts: 1483
Joined: Wed Jun 18, 2008 8:32 am
Location: Surrey

Re: preventing header injection

Post by jaoudestudios »

Why dont you use an existing library to do it, then you dont have to worry about an injections.

I recommend Zend mail - I have not used it but I have read about it and I will definitely use it next time as it appears to be very good.
oboedrew
Forum Commoner
Posts: 78
Joined: Fri Feb 20, 2009 1:17 pm

Re: preventing header injection

Post by oboedrew »

Thanks for the recommendation, but it doesn't really address my question. I'm not looking for a ready-made program or script. I'm trying to better understand this particular aspect of php security so that I can more safely implement my own scripts.

Cheers,
Drew
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: preventing header injection

Post by kaisellgren »

You do not need to strip those things. To be honest, black listing is not the way to do it really.

Make sure that no one can alter the header structure of your email. For instance, a common case is that you allow people to directly put input into "From: " part of the header. This would lead into header manipulation.
oboedrew
Forum Commoner
Posts: 78
Joined: Fri Feb 20, 2009 1:17 pm

Re: preventing header injection

Post by oboedrew »

My form allows the user to input their name, email address, and email body. The name field accepts only letters, so I'm not worried about it. The email field is checked against a regex for validation, so I'm not worried about it. It's the body field that concerns me. Isn't it possible to manipulate the email's headers by inserting additional headers into the body field? That's what I've read in a handful of articles.

So, no, I'm not giving the user a field that asks specifically for headers, but I'm concerned about the user putting additional headers into the body field, where any characters are allowed.

When the message is sent, it looks like this:
mail("$my_name <$my_email>", 'message sent through contact form', $body, "From: $user_name <$user_email>");
where $body is the text entered into the body field, $user_name is the user's name as entered into the name field, and $user_email is the user's email as entered into the form.

Thanks,
Drew
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: preventing header injection

Post by kaisellgren »

$body will go to the body part of the email. No real danger may happen by allowing someone to put input on it unless you are using multipart mails and someone knows your boundary. In that case he could create multipart emails. You may want to limit the amount of body content accepted and also, RFC specifies a maximum characters per line limit if you want to follow that (recommended).
oboedrew
Forum Commoner
Posts: 78
Joined: Fri Feb 20, 2009 1:17 pm

Re: preventing header injection

Post by oboedrew »

Thanks, Kai. That's good to know. Since the only header the user is able to enter is the "From:" address, it sounds like checking the email address entered against a regex is all the protection I need, right?

I use wordwrap to limit messages to 70 characters per line, as recommended in the PHP Manual. Does this recommendation correspond to the RFC specification?

Cheers,
Drew
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: preventing header injection

Post by kaisellgren »

oboedrew wrote:Thanks, Kai. That's good to know. Since the only header the user is able to enter is the "From:" address, it sounds like checking the email address entered against a regex is all the protection I need, right?
I would recommend you to show us this regular expression.
oboedrew wrote:I use wordwrap to limit messages to 70 characters per line, as recommended in the PHP Manual. Does this recommendation correspond to the RFC specification?
I do not remember the limit from the top of my head. I guess that is it.
oboedrew
Forum Commoner
Posts: 78
Joined: Fri Feb 20, 2009 1:17 pm

Re: preventing header injection

Post by oboedrew »

Code: Select all

if(!preg_match('|^[A-Za-z0-9_.-]+@[A-Za-z0-9_.-]+\.[A-Za-z]{2,6}$|', $email)){
    displays error message and doesn't send message
}
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: preventing header injection

Post by Benjamin »

oboedrew wrote:The name field accepts only letters
You're validating this server side right?
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: preventing header injection

Post by kaisellgren »

Nope that regular expression does not validate properly.

You need to use D pattern modifier.
oboedrew
Forum Commoner
Posts: 78
Joined: Fri Feb 20, 2009 1:17 pm

Re: preventing header injection

Post by oboedrew »

Yes, astions, each field is checked against a regex in the php script processing the form.

Kai, what is the D pattern modifier? I've check this regex against a variety of email addresses using http://www.regextester.com/ and http://www.fileformat.info/tool/regex.htm, and it looks like it's working fine.

Thanks,
Drew
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: preventing header injection

Post by kaisellgren »

Looks like. Add letter "D" into the end of it after the delimiter. ;)

http://fi.php.net/manual/en/reference.p ... ifiers.php
oboedrew
Forum Commoner
Posts: 78
Joined: Fri Feb 20, 2009 1:17 pm

Re: preventing header injection

Post by oboedrew »

I'm not sure I understand the description of the D pattern modifier. Something about ensuring that the final character isn't a newline. If it makes a difference, before checking the email against that regex I run it through trim and htmlentities.

Code: Select all

$email=trim($_POST['email']);
$email=htmlentities($email, ENT_QUOTES, 'UTF-8');
if(!preg_match('|^[A-Za-z0-9_.-]+@[A-Za-z0-9_.-]+\.[A-Za-z]{2,6}$|', $email)){
    display error message and redisplay sticky form
}
Can you explain in more detail what the D pattern modifier does? What is the security risk if it is not used?

Thanks,
Drew
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: preventing header injection

Post by kaisellgren »

The modifier D makes the $ character to match the very end of the subject. Otherwise, it won't.

You don't need those two lines. Just add the pattern modifier and your email validation does not have holes. However, do you know that you have a very strict email filter? o'hara@gmail.com nor o'reilly@hotmail.com can access your site. ;)
Post Reply