您的位置:首页 > 其它

通过JAXB看XML外部实体注入(XML External Entity)

2016-07-14 10:48 1086 查看
我们先使用JAXB提供的注解标记下java类和XML映射关系:

package jaxb;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Student {

@XmlElement(name = "name")
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Student [name=" + name + "]";
}

}


下面这个类使用JAXB的API进行对象和xml直接的相互转换:

package jaxb;

import java.io.FileInputStream;
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

public class Main {

public static void main(String[] args) throws Exception {
String xml = readContent("src/jaxb/1.xml");
Object obj = xmlToObjectXXE(xml, Student.class);
System.out.println(objectToXML(obj, Student.class));
}

public static String readContent(String file) throws Exception {
FileInputStream input = new FileInputStream(file);
byte[] content = new byte[2 * 1024];
int realBytes = input.read(content);
input.close();
return new String(content, 0, realBytes, "UTF-8");
}

public static Object xmlToObjectXXE(String xml, Class<?> klass) throws Exception {
JAXBContext context = JAXBContext.newInstance(klass);
Unmarshaller unmarshaller = context.createUnmarshaller();
return unmarshaller.unmarshal(new StringReader(xml));
}

public static Object xmlToObjectSafe(String xml, Class<?> klass) throws Exception {
JAXBContext context = JAXBContext.newInstance(klass);

XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xif.setProperty(XMLInputFactory.SUPPORT_DTD, true);
XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml));

Unmarshaller unmarshaller = context.createUnmarshaller();
return unmarshaller.unmarshal(xsr);
}

public static String objectToXML(Object obj, Class<?> klass) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(klass);
Marshaller marshaller = jaxbContext.createMarshaller();

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);

StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
writer.close();

return writer.toString();
}
}
xmlToObjectXXE()这个方法解析xml,存在XXE注入;而xmlToObjectSafe是安全的解析方式。

比如我们xml内容是:

<!DOCTYPE student[

<!ENTITY my_outer_entity SYSTEM "file:///c:/demo.txt">

]>

<student>
<name>&my_outer_entity;</name>
</student>


如果使用xmlToObjectXXE得到的结果是:可以明显地看到XXE攻击,读取了c:/demo.txt的内容



如果使用xmlToObjectSafe解析得到结果是:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  XXE JAXB