xml介绍
XML是一种非常流行的标记语言,在解析外部实体的过程中,XML解析器可以根据URL中指定的方案(协议)来查询各种网络协议和服务(DNS,FTP,HTTP,SMB等)。外部实体对于在文档中创建动态引用非常有用,这样对引用资源所做的任何更改都会在文档中自动更新。但是,在处理外部实体时,可以针对应用程序启动许多攻击。这些攻击包括泄露本地系统文件,这些文件可能包含密码和私人用户数据等敏感数据,或利用各种方案的网络访问功能来操纵内部应用程序。通过将这些攻击与其他实现缺陷相结合,这些攻击的范围可以扩展到客户端内存损坏,任意代码执行,甚至服务中断,具体取决于这些攻击的上下文。
内部实体
XML文档有自己的一个格式规范,这个格式规范是由一个叫做DTD(documenttypedefinition)的东西控制的。
?xmlversion="1.0"?//这一行是XML文档定义!DOCTYPEmessage[!ELEMENTmessage(receiver,sender,header,msg)!ELEMENTreceiver(#PCDATA)!ELEMENTsender(#PCDATA)!ELEMENTheader(#PCDATA)!ELEMENTmsg(#PCDATA)
上面这个DTD就定义了XML的根元素是message,然后跟元素下面有一些子元素,那么XML到时候必须像下面这么写
messagereceiverMyself/receiversenderSomeone/senderheaderTheReminder/headermsgThisisanamazingbook/msg/message
其实除了在DTD中定义元素(其实就是对应XML中的标签)以外,我们还能在DTD中定义实体(对应XML标签中的内容),毕竟XML中除了能标签以外,还需要有些内容是固定的
?xmlversion="1.0"encoding="ISO--1"?!DOCTYPEfoo[!ELEMENTfooANY!ENTITYxxe"test"]
这里定义元素为ANY说明接受任何元素,但是定义了一个xml的实体(实体其实可以看成一个变量,到时候我们可以在XML中通过符号进行引用),那么XML就可以写成这样
示例代码:
credsuserxxe;/userpassmypass/pass/creds
我们使用xxe对上面定义的xxe实体进行了引用,到时候输出的时候xxe就会被"test"替换。
外部实体
示例代码:
?xmlversion="1.0"encoding="ISO--1"?!DOCTYPEfoo[!ELEMENTfooANY!ENTITYxxeSYSTEM"file:///c:/test.dtd"]credsuserxxe;/userpassmypass/pass/creds
当然,还有一种引用方式是使用引用公用DTD的方法,语法如下:
!DOCTYPE根元素名称PUBLIC“DTD标识名”“公用DTD的URI”
我们上面已经将实体分成了两个派别(内部实体和外部外部),但是实际上从另一个角度看,实体也可以分成两个派别(通用实体和参数实体)。
通用实体
用实体名;在DTD中定义,在XML文档中引用
?xmlversion="1.0"encoding="utf-8"?!DOCTYPEupdateProfile[!ENTITYfileSYSTEM"file:///c:/windows/win.ini"]updateProfilefirstnameJoe/firstnamelastnamefile;/lastname.../updateProfile
参数实体
(1)使用%实体名(这里面空格不能少)在DTD中定义,并且只能在DTD中使用%实体名;引用(2)只有在DTD文件中,参数实体的声明才能引用其他实体(3)和通用实体一样,参数实体也可以外部引用
示例代码:
!ENTITY%an-element"!ELEMENTmytag(subtag)"!ENTITY%remote-dtdSYSTEM"