在我的Web应用程序中,用户可以输入文本数据.此数据可以显示给其他用户,原始作者也可以返回并编辑他们的数据.我正在寻找安全地逃避这些数据的正确方法.
我只是在进行sql清理,因此所有内容都会在读取时存储.假设我在数据库中有"似曾相识".或者,更加极端,一个标签.这可能是有效的,甚至不是恶意的输入.
我正在htmlentities()
出路以确保一切都被逃脱.问题是html和输入字段对待事物的方式不同.我想确保它在HTML中是安全的,但是作者在编辑文本时会看到他们在输入字段中输入的内容.我也使用jQuery动态填充表单字段和数据.
如果我这样做:
=htmlentities("déjà vu");?>
">
页面源放入déjà vu
两个地方(我不得不反击或者你会看到"似曾相识"!)问题是输出是正确的,但输入只显示转义文本.如果用户重新提交表单,他们会双重逃避并破坏他们的输入.
我知道我仍然需要清理进入该领域的文本,否则你可以结束价值报价并做坏事.我找到的唯一解决方案就是这个.我再次使用jQuery.
var temp = $("").html("=htmlentities("déjà vu");?>"); $("input").val(temp.html());
这有效,因为它导致div将转义的文本作为编码字符读取,然后jquery将这些编码的字符复制到输入标记,并进行适当保留.
所以我的问题是:这仍然是安全的,还是某处有安全漏洞?更重要的是,这是唯一/正确的方法吗?我是否遗漏了有关html和字符编码如何工作的问题,这使得这个问题难以解决?
这实际上是错误的,我过度简化了我的例子,以至于它不起作用.问题实际上是因为我使用jQuery的val()将文本插入到字段中.
这样做的原因是表单是动态的 - 用户可以随意添加或删除字段,因此它们是在页面加载后生成的.
所以似乎jQuery正在逃避数据进入输入,但它还不够好 - 如果我自己不做任何事情,用户仍然可以放入标签,查杀代码并插入恶意代码.但是这里有另一个论点要做.由于只有原作者才能在输入框中看到文字,我是否应该打扰?基本上他们可以执行XSS攻击的唯一人就是他们自己.
对不起,我无法重现你描述的行为.我一直使用htmlspecialchars()
(它的任务基本相同htmlentities()
),它永远不会导致任何形式的双重编码.页面源显示déjà vu
在两个地方(当然!这就是重点!)但是呈现的页面显示了适当的值,这是发送回服务器的内容.
你可以发布一个完整的自包含代码片段,表现出这样的行为吗?
更新:一些测试代码:
回答更新的问题¿foo?'; if( !isset($_GET['foo']) ){ $_GET['foo'] = $default_value; } ?>
htmlentities()
顾名思义,该函数在生成HTML输出时使用.这就是为什么它在你的第二个例子中没什么用处:JavaScript 不是 HTML.它是一种自己的语言,有自己的语法.
现在,您要解决的问题是如何生成遵循以下两个规则的输出:
它是JavaScript中的有效字符串.
它可以安全地嵌入HTML文档中.
我知道的#1最接近的PHP函数是json_encode().由于JSON语法是JavaScript的子集,因此如果您使用PHP字符串提供它,它将输出JavaScript字符串.
就像#2一样,一旦浏览器进入JavaScript块,它就会期望一个标签离开它.json_encode()函数负责处理并正确转义它(
<\/script>
).
我修改过的测试代码:
¿foo?'; if( !isset($_GET['foo']) ){ $_GET['foo'] = $default_value; } ?>
注意:utf8_encode()
从ISO-8859-1转换为UTF-8,如果您的数据已经是UTF-8(推荐),则不需要.