Page 1 of 2
preventing header injection
Posted: Thu Mar 12, 2009 10:23 am
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
Re: preventing header injection
Posted: Thu Mar 12, 2009 2:19 pm
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.
Re: preventing header injection
Posted: Thu Mar 12, 2009 3:42 pm
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
Re: preventing header injection
Posted: Fri Mar 13, 2009 6:28 am
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.
Re: preventing header injection
Posted: Fri Mar 13, 2009 10:29 am
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
Re: preventing header injection
Posted: Fri Mar 13, 2009 10:42 am
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).
Re: preventing header injection
Posted: Fri Mar 13, 2009 11:51 am
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
Re: preventing header injection
Posted: Sat Mar 14, 2009 10:01 am
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.
Re: preventing header injection
Posted: Sun Mar 15, 2009 9:53 pm
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
}
Re: preventing header injection
Posted: Sun Mar 15, 2009 10:17 pm
by Benjamin
oboedrew wrote:The name field accepts only letters
You're validating this server side right?
Re: preventing header injection
Posted: Mon Mar 16, 2009 10:12 am
by kaisellgren
Nope that regular expression does not validate properly.
You need to use D pattern modifier.
Re: preventing header injection
Posted: Mon Mar 16, 2009 11:25 am
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
Re: preventing header injection
Posted: Mon Mar 16, 2009 11:36 am
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
Re: preventing header injection
Posted: Mon Mar 16, 2009 12:07 pm
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
Re: preventing header injection
Posted: Mon Mar 16, 2009 12:25 pm
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.
