我是一名PHP新手,正在研究基本的表单验证脚本。我知道输入过滤和输出转义对于安全性原因都至关重要。我的问题是我下面编写的代码是否足够安全?首先是一些澄清说明。
这是(略微清理过的)代码:
$clean = array();
$html = array();
$_POST['fname'] = filter_var($_POST['fname'], FILTER_SANITIZE_STRING);
$clean['fname'] = $_POST['fname'];
$html['fname'] = htmlentities($clean['fname'], ENT_QUOTES, 'UTF-8');
if ($_POST['fname'] == "") {
$formerrors .= 'Please enter a valid first name.<br/><br/>';
}
else {
$formerrors .= 'Name is valid!<br/><br/>';
}
感谢您的帮助!
〜贾里德
答案 0 :(得分:5)
据我所知,出于安全原因,输入过滤和输出转义都很重要。
我想说输出转义对于安全性和正确性至关重要,输入过滤是深度防御和强制执行特定应用程序规则的潜在有用措施。
输入过滤步骤和输出转义步骤必然是单独的关注点,并且不能组合成一个步骤,尤其是因为有许多不同类型的输出转义,并且必须为每个输出上下文选择正确的输出(例如,页面中的HTML转义,URL转义以进行链接,SQL转义等等。
不幸的是,PHP在这些问题上传统上非常模糊,因此提供了许多可能误导您的混合消息功能。
在下面的示例字段中,该字段是纯文本,因此我需要做的就是清理它。
是。唉,FILTER_SANITIZE_STRING
绝不是一个理智的杀菌者。它完全删除了一些内容(strip_tags
,这本身就非常不合理),同时HTML转义其他内容。例如,引号变为"
。这是胡说八道。
相反,对于输入消毒,请查看:
检查它是您正在使用的编码的有效字符串(希望是UTF-8;请参阅例如this regex);
删除控制字符,U + 0000-U + 001F和U + 007F-U + 009F。仅在故意的多行文本字段上允许换行;
对于内容模型比任意文本字符串更具体的数据,验证输入在逐个字段的基础上符合应用程序要求。虽然你的转义应该正确处理一个<
字符,但是在没有意义的字段中尽早摆脱它可能是一个好主意。
对于输出转义步骤,我通常更喜欢htmlspecialchars()
到htmlentities()
,尽管正确使用UTF-8
参数可以阻止后一个函数以通常的方式打破。< / p>
答案 1 :(得分:1)
根据您要保护的内容,您调用的过滤器可能是overactive(请参阅注释)。注射方式你应该是安全的,因为你正在使用预备语句(见this answer)
在设计说明中,您可能希望先过滤,然后检查空值。这样做可以缩短代码;)
答案 2 :(得分:0)
我理解输入过滤......对于安全原因至关重要。
这是错误的陈述 虽然在某些情况下它是正确的,但在这种普遍的形式下,它可以做到没有好处,但却有错误的安全感。
我需要做的就是消毒它。
没有“一般消毒”这样的事情。您必须了解每个特定情况及其局限性。例如,对于数据库,您需要使用多种不同的清理技术,而不是一种。而对于文件名,它将完全不同。
我正在使用预准备语句进行数据库交互。
因此,您根本不应该触摸数据。请保持原样。
这是(略微清理过的)代码:
您的代码似乎有些过分 您正在清理两次HTML数据,而根本不需要它。 由于某种原因,你提出了成功的错误。
我是这样做的
$formerrors = '';
if ($_POST['fname'] == "") {
$formerrors .= 'Please enter a valid first name.<br/><br/>';
}
if (!$formerrors) {
$html = array();
foreach ($_POST as $key => $val) {
$html[$key] = htmlspecialchars($val,ENT_QUOTES);
}
}