我的在线研究似乎表明,首字母和姓氏不应经过大量验证,以适应各种名称。事实上,人们甚至主张不对名称进行任何验证。但是,通过输入字段进行xss攻击的可能性让我很担心。我检查了谷歌命名指南,他们看起来很放松,允许unicode字符以及“%$#^& * ....”等内容!!
那么,最好的方法是什么,我该如何平衡呢?
ps - 我不打算在这里引发争论。我真的很困惑,需要帮助了解最佳方法!答案 0 :(得分:0)
验证和XSS是两个截然不同的概念。你无法平衡它们。你不能“有时允许XSS”。您也不希望允许无意义的输入,或者您不能使用的输入。如果你需要一个电子邮件的东西,你可以允许用户输入“mailme at gmail dot com”,但是如果你不知道如何解析它,那么首先允许这个作为输入是没有意义的。
当您谈到验证“名字字段”时,您会问自己:“我希望在此字段中接受哪种数据,以及在此字段中我不想接受哪种数据?”。我不知道“%”可以成为名字的一部分的语言,因此禁止这个角色可能是一个安全的选择。你必须单独解决这个问题,甚至不用考虑XSS。如果一个字符或一系列字符作为您想要知道的事物的值没有意义,则不应包含它。如果一个角色确实有意义,那么你不应该另外做出决定,因为它有一些特殊的含义。
XSS是将错误转义(用户)输入返回到浏览器的问题,允许可能的攻击者加载/运行第三方脚本。它与验证无关。如果字符“a”可能不安全,您是否会从名字字段中禁止它?解决方案可以在定义中找到:当且仅当用户输入被错误地转义时,问题才存在。
考虑一下如何将这些数据发送给用户。我以输入字段<input value="" />
为例,但如果您要将其放在textarea中,则需要更改数据。将其插入<div></div>
标记之间需要完全不同的东西,将其插入<script></script>
标记内的脚本中需要的内容与以前的所有内容不同。没有一个适合所有人的解决方案。
对于输入字段示例,请在此输入字段中找出哪些字符具有特殊含义。值属性("
中的value=""
)的分隔符是具有特殊含义的字符之一。如果有任何其他特殊字符,您可以在随附的文档中找到它们。你必须逃避这些角色。逃避是从角色中删除特殊含义的行为。您如何做到这一点可以在随附的文档中找到。如果是html中的输入元素,则需要将特殊字符转换为实体形式("
将成为"
)。 Php提供内置函数来执行此操作,但您应始终警惕这样的函数实际执行的操作和如果此函数实际为每个用例提供所需的输出
tl; dr没有平衡。您可以在字段上使用验证来获取实际需要的数据。如果要向用户显示此数据,则必须转义要显示此数据的特殊情况的数据。
示例:让我们看一下以下情况。我们有一个textarea。我们允许字符a-z,&lt;,&gt;,(,),{,},/和;以任何顺序。如果textarea包含其他字符,我们认为无效。如果textarea 有效,我们会将字符放在html文档中<div>
和</div>
之间的textarea中。
从上面的定义中,您可以推导出asdf
是一个有效的输入,而<scri
(绕过错误代理的随机废话)pt>alert();</sc
(更随机的废话){{1} }也是有效输入,但ript>
不是。这就是定义。处理验证的逻辑应该完美地区分这两件事。您可能会注意到第二个有效输入可能会出现问题,但这与验证功能无关。 validate函数仅检查文本是否与我们认为有效输入的描述匹配。
如果textarea中的文本有效,则定义说我们应该将它放在div标签之间。这是你开始担心XSS的地方。有一些字符,即html中具有特殊含义的123
和<
字符。因为它们是有效的输入,所以当我们在html中插入它们时,我们应该删除它们的特殊含义。如果textarea无效,我们什么也做不了。我们将显示一条描述性错误消息,告知它应该如何改进。
下面的伪实现显示了我上面尝试解释的内容。在与服务器通信的实际应用程序中,服务器也应该进行验证,但它应该显示两个概念是如何分开的,并且应该允许您进行测试。
>
$('#billy').on('click', function(e) {
if (validate($('#txt').val())) {
$('#status').text("The textarea is valid. The contents have been inserted as html in the page.");
$('#result').html($('#txt').val());
} else {
$('#status').text("The textarea is INVALID. It contains characters we don't want.");
}
});
$('#betty').on('click', function(e) {
if (validate($('#txt').val())) {
$('#status').text("The textarea is valid. The contents have been inserted as html in the page.");
$('#result').html(escapeforhtml($('#txt').val()));
} else {
$('#status').text("The textarea is INVALID. It contains characters we don't want.");
}
});
function validate(txt) {
return txt.match(/^[a-z{}\/\(\)<>;]*$/);
}
//We know only a limited amount of characters can be inserted.
//From those, < and > are the only characters that have a special
//meaning.
function escapeforhtml(txt) {
return txt.replace(/</g, "<").replace(/>/g, ">");
}