gpt4 book ai didi

java - 使用 JAXB 防止 XXE 攻击

转载 作者:IT老高 更新时间:2023-10-28 20:48:10 26 4
gpt4 key购买 nike

最近,我们对我们的代码进行了安全审计,其中一个问题是我们的应用程序受到了 Xml eXternal Entity (XXE) 攻击。

基本上,该应用程序是一个计算器,通过 Web 服务接收 XML 格式的输入。

以下是对我们的应用程序进行此类 XXE 攻击的示例:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<foo:calculateStuff>
<!--Optional:-->
<xmlInput><![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE currency [
<!ENTITY include SYSTEM "file:///d:/" >]>
<calcinput>...</calcinput>
]]></xmlInput>
</foo:calculateStuff>
</soapenv:Body>
</soapenv:Envelope>

如您所见,我们可以引用指向外部文件 ("file:///d:/") 的实体。

关于 XML 输入本身(<calcinput>...</calcinput> 部分)是用 JAXB (v2.1) 解码的。 Web 服务部分基于 jaxws-rt (2.1)。

我需要做些什么来保护我的网络服务?

最佳答案

JAXB

您可以通过从具有 IS_SUPPORTING_EXTERNAL_ENTITIES 和/或 XMLInputFactory.SUPPORT_DTDXMLStreamReader 解码来防止 Xml 外部实体 (XXE) 攻击属性设置为 false

JAX-WS

JAX-WS 实现应该为您解决这个问题。如果不是,我建议针对特定实现打开一个错误。


示例

演示

package xxe;

import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Customer.class);

XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/xxe/input.xml"));

Unmarshaller unmarshaller = jc.createUnmarshaller();
Customer customer = (Customer) unmarshaller.unmarshal(xsr);

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}

}

input.xml

此 XML 文档包含一个实体,该实体已设置为获取我用于创建此示例的文件列表。

<?xml version="1.0"?>
<!DOCTYPE customer
[
<!ENTITY name SYSTEM "/Users/bdoughan/Examples/src/xxe/">
]
>
<customer>
<name>&name;</name>
</customer>

客户

package xxe;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Customer {

private String name;

public String getName() {
return name;
}

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

}

输出 - 默认配置

默认情况下实体将被解析。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
<name>Customer.java
Demo.java
input.xml
</name>
</customer>

XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES 属性设置为 false

时的输出

设置此属性后,实体不会被解析。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
<name></name>
</customer>

XMLInputFactory.SUPPORT_DTD 属性设置为 false

时的输出

当设置此属性时,会引发异常以尝试解析实体。

Exception in thread "main" javax.xml.bind.UnmarshalException
- with linked exception:
[javax.xml.stream.XMLStreamException: ParseError at [row,col]:[8,15]
Message: The entity "name" was referenced, but not declared.]
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:436)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:372)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:342)
at xxe.Demo.main(Demo.java:18)
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[8,15]
Message: The entity "name" was referenced, but not declared.
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:598)
at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:196)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:370)
... 2 more

关于java - 使用 JAXB 防止 XXE 攻击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12977299/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com