preventing header injection
Moderator: General Moderators
preventing header injection
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
Thanks,
Drew
- jaoudestudios
- DevNet Resident
- Posts: 1483
- Joined: Wed Jun 18, 2008 8:32 am
- Location: Surrey
Re: preventing header injection
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.
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
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
Cheers,
Drew
- kaisellgren
- DevNet Resident
- Posts: 1675
- Joined: Sat Jan 07, 2006 5:52 am
- Location: Lahti, Finland.
Re: preventing header injection
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.
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
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
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
- kaisellgren
- DevNet Resident
- Posts: 1675
- Joined: Sat Jan 07, 2006 5:52 am
- Location: Lahti, Finland.
Re: preventing header injection
$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
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
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
- kaisellgren
- DevNet Resident
- Posts: 1675
- Joined: Sat Jan 07, 2006 5:52 am
- Location: Lahti, Finland.
Re: preventing header injection
I would recommend you to show us this regular expression.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 do not remember the limit from the top of my head. I guess that is it.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?
Re: preventing header injection
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
You're validating this server side right?oboedrew wrote:The name field accepts only letters
- kaisellgren
- DevNet Resident
- Posts: 1675
- Joined: Sat Jan 07, 2006 5:52 am
- Location: Lahti, Finland.
Re: preventing header injection
Nope that regular expression does not validate properly.
You need to use D pattern modifier.
You need to use D pattern modifier.
Re: preventing header injection
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
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
- kaisellgren
- DevNet Resident
- Posts: 1675
- Joined: Sat Jan 07, 2006 5:52 am
- Location: Lahti, Finland.
Re: preventing header injection
Looks like. Add letter "D" into the end of it after the delimiter. 
http://fi.php.net/manual/en/reference.p ... ifiers.php
http://fi.php.net/manual/en/reference.p ... ifiers.php
Re: preventing header injection
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.
Can you explain in more detail what the D pattern modifier does? What is the security risk if it is not used?
Thanks,
Drew
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
}Thanks,
Drew
- kaisellgren
- DevNet Resident
- Posts: 1675
- Joined: Sat Jan 07, 2006 5:52 am
- Location: Lahti, Finland.
Re: preventing header injection
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.
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.