WEB安全第六课 HTML语言 之三 HTML实体编码 |
让我们再回到字符编码的话题上来吧。就像开头提过的那样,某些保留字符出现在文本节点和标签值里是不安全的,在XHTML里这些字符会立刻导致语法出错。要想安全地使用这些字符(以及更方便地嵌人高位字节文本),开发人员应该使用一套名叫实体编码(entity encoding)的简单编码策略,这套编码是以&符号开头,以逗号结尾的。
这种编码方式最为常用的做法是插入某些预先定义好的命名实体(named entity)。在XML里,只有不多的此类实体,但在HTML规范里,却散布着好几百个这类命名实体,并且所有的常用浏览器都支持这些用法。在这套编码里,&1t;用于插入一个左尖括号;>;代表右尖括号;&替换&符号自身;而→则代表个好看的Unicode箭头。 🧓👔📏💩👏 注意:在XHTML文档里,可以通过指令<!ENTITY>定义额外的命名实体,并把它解析为内部指定的字符串或一个外部文件URL的内容(如果能用来处理不受信任的内容,后者明显是不安全的;这种攻击有时候就叫外部XML实体攻击(External XML Entity)或简称XXE)。 除了命名实体,还可以插人以任意十进制ASCII码或Unicode字符编码,样式为“&#数值;”的标记符。在这种用法里,<映射为左尖括号;>为右尖括号;而😹——我真不是在开玩笑,是一个名为“留下欢欣泪水的微笑猫脸”的Unicode6.0字符。十六进制的标记符则是在编码数字前面再加个“x”。在这种稍有变型的编码里,左尖括号变成了<,其他以此类推。 HTML解析器能识别在文本节点和参数值里的实体编码,并在内存里创建文档树的表现形式时,透明地对这些编码进行解码。因此,以下两个例子在功能上是完全一样的: 🧑🍳🕶💰🤮🖕 <img src="http://www.examp1e.com"> 以及 <img src="http://www.example.com"> 👃🎢🍞☯🐉 而以下两个例子,实际上却没法真的加载图片,因为这种编码干扰了标签本身的结构: <img src="http://www.example.com"> 💅🌧🍼♻🪰 以及 <img src="http://www.example.com"> 由于实体编码几乎完全透明的行为方式,所以在处理文档内容,做出任何与安全有关的决定时,预先进行正确的分解还原就非常重要了,如果有必要,在输出时还需要恰当地再进行编码,以达到输出安全的目的。要说明这一点请看以下这个例子,以下语法应该被识别为“javascript:伪URL”的绝对引用,而不是一个带着古怪的片段ID,URL路径为“./javascript&”的相对资源: ✋🔥🍽❌🦄 <a href="javascript:alert(1)"> 遗憾的是,甚至识别和解析HTML实体这种简单任务也陷阱多多。例如,在传统的解析中,只要实体名称后面跟着的字符不是字母数字,即使少了最后的分号,实体名也是能被接受的(在Firefbx里,命名实体的名称里甚至可以包括破折号和句号。)数字型实体的问题就更多了,因为数字的后面可以跟任意多个零,导致一个超长的数字串。而如果这个数值高于2^32,这是普通计算机架构能处理的标准上限了,那得到的相应字符可能就会出错。 🧑⚕️🪖💳😈🤳 使用XHTML的开发者也要警惕由于其自身特性而导致的潜在风险。尽管HTML实体在大多数特殊解析模式下并不起作用,但XHTML却和传统的HTML不同,在XHTML里,靠<script>和<style>等标签本身并不能自动切换到特殊解析模式里。必须在脚本或样式表的区块范围里明确地用<![CDATA[...]]>标记出范围,才能达到模式切换的效果。 因此,以下这段由攻击者控制的代码(合理的做法应该是过滤掉尖括号、引号、反斜杠和换行)在HTML里是安全的,但在XHTML里却并非如此: <script>👨⚕️👗🪓🤤🦷 var tmp ='I am harmless! '+alert(l);// Or am I?'; ... </script> WEB安全第六课第四节: ✋🏠🍟📳🐕
帖子热度 1万 ℃
|
|
本来我已决定不会再回任何帖子了,当我览遍无数烂贴、痛恨生不逢时,行走在思想的戈壁荒原、穷山恶水之间,感到前途渺茫、万念俱灰之际,却突然看到这样一篇绝世好贴!我真是热泪纵横、感激涕零告诉自己如此经典之贴是一定要回的!这正是千百年来版友翘首以待的好贴啊!
|