Escape-строка для использования в mail()
Конечно, при использовании MySQL вы используете mysqli_real_escape_string()
и убедитесь, что тип полученного ввода соответствует ожидаемому (строка, число и т. д.), и вы можете быть уверены, что можете использовать его как вход для mysqli_query()
довольно безопасно... верно?
Ну, вопросы:
- Каков наилучший способ избежать строки, которая будет использоваться в
mail()
? - Если получателем электронной почты будет адрес электронной почты, введенный в текстовом поле, с какими вещами я должен быть осторожен, чтобы избежать инъекций или эксплойтов?
У меня есть довольно хорошая идея, как это сделать, но я изучаю лучшие практики по этому вопросу, чтобы узнать, что я что-то упустил или есть лучший способ.
РЕДАКТИРОВАТЬ: Идея этого вопроса не в том, чтобы получить ответ, а в том, чтобы составить исчерпывающий совместный список всех вещей, о которых нужно позаботиться при работе с электронной почтой с помощью PHP.
1 ответ
Идея внедрения электронной почты заключается в том, что злоумышленник вставляет перевод строки (LF) в заголовки сообщений электронной почты, поэтому он добавляет столько заголовков, сколько хочет. Удаление этих перевода строки защитит вас от этой атаки. Для получения подробной информации проверьте http://www.phpsecure.info/v2/article/MailHeadersInject.en.php
Лучшая практика - полагаться на хорошо написанный, часто обновляемый и широко используемый код. Для этого я бы предложил использовать PEAR_MAIL ИЛИ Zend_Mail
Если вы не хотите загружать эти модули или вам нужно, чтобы все было очень просто. Вы можете извлечь функциональность фильтрации из этих модулей. Хотя я рекомендую использовать их и часто обновлять библиотеку, чтобы в случае появления новой атаки вам просто нужно было обновить библиотеку (Pear или Zend), и все готово.
Это функция, которая очищает заголовки в пакете Pear Mail:
function _sanitizeHeaders(&$headers)
{
foreach ($headers as $key => $value) {
$headers[$key] =
preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
null, $value);
}
}
Zend_Mail использует другой фильтр для электронной почты, имени и других полей:
function _filterEmail($email)
{
$rule = array("\r" => '',
"\n" => '',
"\t" => '',
'"' => '',
',' => '',
'<' => '',
'>' => '',
);
return strtr($email, $rule);
}
function _filterName($name)
{
$rule = array("\r" => '',
"\n" => '',
"\t" => '',
'"' => "'",
'<' => '[',
'>' => ']',
);
return trim(strtr($name, $rule));
}
function _filterOther($data)
{
$rule = array("\r" => '',
"\n" => '',
"\t" => '',
);
return strtr($data, $rule);
}