阻止 php 中的邮件注入拦截某些字符 \r、\n、%0A、%0D
Preventing mail injection in php intercepting some characters \r, \n, %0A, %0D
我想阻止人们使用在 php 中用于邮件注入的特殊字符发送垃圾邮件。例如 \n
和 \r
用于连接多个 headers,因此 %0A
和 %0D
也是如此。所以我写了一个正则表达式来匹配它们。但我怀疑我的正则表达式效率不高……有些事情让我觉得我在写一些无法使用的东西……感谢任何帮助,谢谢。
这是我想做的一个基本示例...
if (!preg_match('/^[^\s]./', $_POST['name']) || (preg_match('/(%0A|%0D|\n+|\r+|;|mime-version:|content-type:|content-transfer-encoding:|subject:|to:|cc:|bcc:)/i', $_POST['name'])) || !(strpos($_POST['name'],'\r') === false) || !(strpos($_POST['name'],'\n') === false)) {
exit("Warning: your Name contains illegal characters! This mail will not be sent!");
} elseif (!preg_match('/^[^\s]./', $_POST['subject']) || (preg_match('/(%0A|%0D|\n+|\r+|;|mime-version:|content-type:|content-transfer-encoding:|subject:|to:|cc:|bcc:)/i', $_POST['subject'])) || !(strpos($_POST['subject'],'\r') === false) || !(strpos($_POST['subject'],'\n') === false)) {
exit("Warning: your Subject contains illegal characters! This mail will not be sent!");
} elseif (!preg_match('/^[a-zA-Z0-9]+([_\.-][a-zA-Z0-9]+)*'.'@([a-zA-Z0-9]+([\.-][a-zA-Z0-9]+))+$/', $_POST['mail'])) {
exit("Warning: your Mail contains no valid email address! This mail will not be sent!");
} elseif (!preg_match('/^[^\s]./', $_POST['message'])) {
exit("Warning: your Message connot be empty! This mail will not be sent!");
} else {
$name = $_POST['name'];
$mail = $_POST['mail'];
$subject = $_POST['subject'];
$message = $_POST['message'];
mail($to, $subject, $message, $headers, "-f$mail") {
exit("Your Mail is sent! Thanks!");
}
为了匹配 \n
、\r
、%0A
和 %0D
我应该如何编写正则表达式?
和
!(strpos($_POST['subject'],'\r') === false)
!(strpos($_POST['subject'],'\n') === false)
挺好的?
谢谢。
我对正则表达式不是很透彻,但我可以通过为您的问题提供替代技巧解决方案来帮助您。
您可以使用以下代码来解决您的问题。
<?php
function sanitize_strings($raw_string) {
return preg_replace("/[^0-9a-zA-Z_\-\\%]+/", "", $raw_string);
}
if( $raw_string == sanitize_strings($raw_string) )
{
echo "No illegal characters found.";
}
else
{
echo "Illegal characters found.";
}
?>
希望这对你有用。 :)
我做了一个测试。测试结果成功!我用不同的方法直接在 localhost
中测试了正则表达式:
<?php
$test = "the dog \n was \r sleeping on the floor";
if (preg_match_all('/(%0A|%0D|\n+|\r+|;|mime-version:|content-type:|content-transfer-encoding:|subject:|to:|cc:|bcc:)/i', $test, $tmp)) {
echo "I found this character: '";
print_r($tmp[1]);
echo "'";
} else {
echo "I cannot find any string searched";
}
?>
结果:
I found this character: 'Array ( [0] => [1] => ) '
查看源代码我可以看到 \n 和 \r
I found this character: 'Array
(
[0] =>
[1] =>
)
'
所以我认为正则表达式构建得很好。
还有我用 strpos()
做的其他测试:
if !(strpos($_POST['subject'],'\n') === false)) {
使用单引号失败,而使用双引号找到 \n...
if !(strpos($_POST['subject'],"\n") === false)) {
结论:正则表达式格式正确,strpos()
需要 "" 来匹配 \n 或 \r。
我想阻止人们使用在 php 中用于邮件注入的特殊字符发送垃圾邮件。例如 \n
和 \r
用于连接多个 headers,因此 %0A
和 %0D
也是如此。所以我写了一个正则表达式来匹配它们。但我怀疑我的正则表达式效率不高……有些事情让我觉得我在写一些无法使用的东西……感谢任何帮助,谢谢。
这是我想做的一个基本示例...
if (!preg_match('/^[^\s]./', $_POST['name']) || (preg_match('/(%0A|%0D|\n+|\r+|;|mime-version:|content-type:|content-transfer-encoding:|subject:|to:|cc:|bcc:)/i', $_POST['name'])) || !(strpos($_POST['name'],'\r') === false) || !(strpos($_POST['name'],'\n') === false)) {
exit("Warning: your Name contains illegal characters! This mail will not be sent!");
} elseif (!preg_match('/^[^\s]./', $_POST['subject']) || (preg_match('/(%0A|%0D|\n+|\r+|;|mime-version:|content-type:|content-transfer-encoding:|subject:|to:|cc:|bcc:)/i', $_POST['subject'])) || !(strpos($_POST['subject'],'\r') === false) || !(strpos($_POST['subject'],'\n') === false)) {
exit("Warning: your Subject contains illegal characters! This mail will not be sent!");
} elseif (!preg_match('/^[a-zA-Z0-9]+([_\.-][a-zA-Z0-9]+)*'.'@([a-zA-Z0-9]+([\.-][a-zA-Z0-9]+))+$/', $_POST['mail'])) {
exit("Warning: your Mail contains no valid email address! This mail will not be sent!");
} elseif (!preg_match('/^[^\s]./', $_POST['message'])) {
exit("Warning: your Message connot be empty! This mail will not be sent!");
} else {
$name = $_POST['name'];
$mail = $_POST['mail'];
$subject = $_POST['subject'];
$message = $_POST['message'];
mail($to, $subject, $message, $headers, "-f$mail") {
exit("Your Mail is sent! Thanks!");
}
为了匹配 \n
、\r
、%0A
和 %0D
我应该如何编写正则表达式?
和
!(strpos($_POST['subject'],'\r') === false)
!(strpos($_POST['subject'],'\n') === false)
挺好的?
谢谢。
我对正则表达式不是很透彻,但我可以通过为您的问题提供替代技巧解决方案来帮助您。
您可以使用以下代码来解决您的问题。
<?php
function sanitize_strings($raw_string) {
return preg_replace("/[^0-9a-zA-Z_\-\\%]+/", "", $raw_string);
}
if( $raw_string == sanitize_strings($raw_string) )
{
echo "No illegal characters found.";
}
else
{
echo "Illegal characters found.";
}
?>
希望这对你有用。 :)
我做了一个测试。测试结果成功!我用不同的方法直接在 localhost
中测试了正则表达式:
<?php
$test = "the dog \n was \r sleeping on the floor";
if (preg_match_all('/(%0A|%0D|\n+|\r+|;|mime-version:|content-type:|content-transfer-encoding:|subject:|to:|cc:|bcc:)/i', $test, $tmp)) {
echo "I found this character: '";
print_r($tmp[1]);
echo "'";
} else {
echo "I cannot find any string searched";
}
?>
结果:
I found this character: 'Array ( [0] => [1] => ) '
查看源代码我可以看到 \n 和 \r
I found this character: 'Array
(
[0] =>
[1] =>
)
'
所以我认为正则表达式构建得很好。
还有我用 strpos()
做的其他测试:
if !(strpos($_POST['subject'],'\n') === false)) {
使用单引号失败,而使用双引号找到 \n...
if !(strpos($_POST['subject'],"\n") === false)) {
结论:正则表达式格式正确,strpos()
需要 "" 来匹配 \n 或 \r。