哪一个应该首先执行?消毒或验证

naa*_*nin 8 php validation sanitize

我的注册表单中有一个name字段,其中包含一个字段,它将存储在数据库中的一个字段中user_name varchar(20).很明显,如果我使用以下代码验证此字段,我应验证用户输入:

<?php
 if(emptiy($_pos['name']) || strlen($_post['name'])>20)
 //send an not valid input error
 else{
 $name=htmlspcialchars($_post['name']);
 //check for sql injection;
 //insert name into database;}
?>
Run Code Online (Sandbox Code Playgroud)

如果用户插入一个名称,如<i> some one </i>字符串长度为17,那么else部分将performe和名称将是&lt;i&gt some one &lt;/i&gt;长度为28,这将导致插入到db.in这次,如果我向用户发送错误,他/他她的投入太长,他会感到困惑.我该怎么办?什么是最好的方法?

Bri*_*anH 6

一般来说,人们应首先消毒 - "为了你的保护,他们的保护." 这包括剥离任何无效字符(当然,字符编码敏感).如果一个字段应该只包含字符和空格,那么删除任何不是第一个字符和空格.

完成后,您将验证结果 - 是否已使用的名称(对于唯一字段),是否为正确的大小,是否为空白?

您提供的原因恰恰是正确的 - 最大化用户体验.如果可以避免,请不要混淆用户.这有助于防止愚蠢的复制和粘贴行为,但你必须要小心 - 如果我希望我的名字记录为"Ke $ h @",我可能会或可能不会将其更改为"Keh".

其次,它也是为了防止错误.

如果要创建不允许使用特殊字符的用户名,会发生什么?如果我输入"Brian",并且您的系统拒绝它作为我们已经使用的名称,那么我提交"Brian $"?首先你验证它,它没有被使用,然后你删除特殊字符,你留下"布莱恩".哦哦 - 现在你要么必须验证AGAIN,否则你会得到一个奇怪的错误:帐户创建失败(例如,如果你的数据库设置为需要唯一的用户名),或者更糟糕的是它会成功并覆盖/腐败发生在用户用户帐户中.

另一个例子是最小字段长度:如果你需要一个名字至少3个字母长,只接受字母,我输入"否"你拒绝它; 但如果我输入"no @#$%",你可能会说它有效(足够长),消毒它,现在它已经无效了,等等.

避免这种情况的简单方法是首先进行消毒,然后您不必再考虑验证.

但是,Niet在存储之前不对数据进行编码是正确的; 在适当的时候将输出设置为HTML通常要容易得多,然后在你只想要纯文本(进入文本框,JSON字符串等)时记住解码它.您将使用的大多数测试用例都不包含HTML实体的数据,因此很容易引入不易被捕获的愚蠢错误.

最大的问题是,当引入这样的错误时,它很快就会导致数据损坏,而且不容易解决.示例:您有纯文本,将其作为html实体错误地输出到文本字段,表单被提交回来并重新编码...每次打开/重新提交时,它都会被重新编码.对于繁忙的站点/表单,您最终可能会有数千个不同编码的条目,没有明确的方法来确定哪些应该是什么,哪些不是HTML编码的.

保护注入是好的,但HTML编码不是设计(并且不能依赖)来做到这一点.

  • 您应该让用户知道您必须清理输入 - 我什至会建议在这种情况下,当用户输入无效时,您会向用户给出错误。 (2认同)