使用 JAXB 防止 XXE 攻击 [英] Prevent XXE Attack with JAXB

查看:46
本文介绍了使用 JAXB 防止 XXE 攻击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我们对我们的代码进行了安全审核,其中一个问题是我们的应用程序受到了Xml 外部实体 (XXE) 攻击.

Recently, we had a security audit on our code, and one of the problem is that our application is subject to the Xml eXternal Entity (XXE) attack.

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

Basically, the application is a calculator that receives inputs as XML, through a Web-Service.

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

Here is an example of such an XXE attack on our application:

<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:/").

As you can see, we can refer to an entity that points to an external file ("file:///d:/").

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

Regarding the XML input itself (the <calcinput>...</calcinput> part) is unmarshalled with JAXB (v2.1). The web-service part is based on jaxws-rt (2.1).

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

What do I need to do to secure my web-service?

推荐答案

JAXB

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

You can prevent the Xml eXternal Entity (XXE) attack by unmarshalling from an XMLStreamReader that has the IS_SUPPORTING_EXTERNAL_ENTITIES and/or XMLInputFactory.SUPPORT_DTD properties set to false.

JAX-WS

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

A JAX-WS implementation should take care of this for you. If it doesn't I would recommend opening a bug against the specific implmententation.

示例

演示

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 文档包含一个实体,该实体已设置为获取我用于创建此示例的文件列表.

This XML document contains an entity that has been setup to get the listing of files I used to create this example.

<?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;
    }

}

输出 - 默认配置

默认情况下将解析实体.

By default the entity will be resolved.

<?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

设置此属性后,实体未解析.

When this property is set the entity is not resolved.

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

XMLInputFactory.SUPPORT_DTD 属性设置为 false

当设置此属性时,会抛出异常以尝试解析实体.

When this property is set an exception is thrown trying to resolve the entity.

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

这篇关于使用 JAXB 防止 XXE 攻击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆