最近、コードのセキュリティ監査を実施しましたが、問題の1つは、アプリケーションが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>
part)は、JAXB(v2.1)で非整列化されます。 Webサービス部分は、jaxws-rt(2.1)に基づいています。
Webサービスを保護するために何をする必要がありますか?
[〜#〜] jaxb [〜#〜]
IS_SUPPORTING_EXTERNAL_ENTITIES
および/またはXMLInputFactory.SUPPORT_DTD
プロパティがXMLStreamReader
に設定されているfalse
から非整列化することにより、Xml eXternal Entity(XXE)攻撃を防ぐことができます。
JAX-WS
JAX-WS実装がこれを処理します。そうでない場合は、特定の実装に対してバグを開くことをお勧めします。
[〜#〜] example [〜#〜]
デモ(
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