是否有任何编码方案能够对双重(或更多)编码或解码具有弹性,并且还能安全抵御 XSS 和 SQL 注入攻击?为了显示:
enc(A) --> A'
enc(A') --> A'
随后:
dec(A') --> A
dec(A) --> A
这在 MVC 框架中很有用,我们指定在发送到控制器之前对内容进行编码。然而,UI 是多层的,并且可能(不经意间)由子视图及其父视图进行双重编码。
是否有任何编码方案能够对双重(或更多)编码或解码具有弹性,并且还能安全抵御 XSS 和 SQL 注入攻击?为了显示:
enc(A) --> A'
enc(A') --> A'
随后:
dec(A') --> A
dec(A) --> A
这在 MVC 框架中很有用,我们指定在发送到控制器之前对内容进行编码。然而,UI 是多层的,并且可能(不经意间)由子视图及其父视图进行双重编码。
不存在这样有用的功能。你想要一个函数enc : X → Y
,dec : Y → X
这样
∀ x ∈ X: dec(enc(x)) = x
(即 是dec
的倒数enc
),
加上额外的约束
∀ x ∈ X : dec(enc(enc(x))) = x
因此,X = Y
和enc(x) = x
!
enc
和dec
函数是相同的,并且是单位函数(返回其输入的函数):
enc(x) = x
dec = enc
这实际上意味着什么?假设我们有一个转义方案,它反斜杠禁止字符'
和\
. 所以我们有
enc( 'foo\ ) = \'foo\\
现在让我们假设用户输入一个字符串\'foo\\
,那么转义的输出应该是
enc( \'foo\\ ) = \\\'foo\\\\
结果与 相同enc(enc( 'foo\ ))
。
没有办法告诉这个函数它是否是一个输出enc
。
当X ≠ Y
(即输出的enc
类型与未编码的输入不同)时,这会发生变化。让我们像这样定义一个多态enc
:
enc : X → Y | Y → Y
dec : Y → X
∀ x ∈ X : dec(enc(x)) = x
∀ x ∈ X : dec(enc(enc(x))) = x
∀ y ∈ Y : enc(y) = y
在大多数编程语言中,这可以通过面向对象来实现:
class Str {
method enc() : EncodedStr { some encoding code }
}
class EncodedStr {
method enc() : EncodedStr { return self } // the unit function
method dec() : Str { some decoding code }
}
也就是∀ x ∈ Str : x.enc.enc.dec = x
等等。。
这个答案的抽象概念可以概括为
您只需要记住您是否已经对该输入进行了编码。
编码不应影响正确开发的应用程序的安全性。在使用时,数据应始终保持安全。编码成为安全问题的唯一时间是,如果运行转义例程,然后运行解码(或者可能是编码)例程,然后使用此数据调用敏感函数。在这种情况下,解码例程总是会破坏转义例程。
例如,以下内容总是不安全的:
mysql_query("select * from user where id ='"+urldecode(addslashes($_GET[id]))+"'")
在这种情况下,参数化可确保无论变量如何编码,生成的字符串都是预期的。如果您总是在使用前立即转义,那么编码永远不会成为问题。