tomj 2002/11/19 10:48:58
Modified: java/test/utils TestXMLUtils.java
java/src/org/apache/axis/encoding
DeserializationContextImpl.java
Log:
Throw an error if we encounter a <!DOCTYPE> DTD when parsing a soap
envelope. This prevents a malicious client from sending a request with
bad or CPU intesive ENTITY directives in a denial of service attack.
Change the XMLUtils test case to omit the DTD. Clean up imports.
Revision Changes Path
1.17 +16 -8 xml-axis/java/test/utils/TestXMLUtils.java
Index: TestXMLUtils.java
===================================================================
RCS file: /home/cvs/xml-axis/java/test/utils/TestXMLUtils.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- TestXMLUtils.java 18 Nov 2002 23:36:57 -0000 1.16
+++ TestXMLUtils.java 19 Nov 2002 18:48:58 -0000 1.17
@@ -1,24 +1,19 @@
package test.utils;
import junit.framework.Test;
-import junit.framework.TestCase;
import junit.framework.TestSuite;
-import org.apache.axis.utils.XMLUtils;
-import org.apache.axis.message.SOAPHandler;
-import org.apache.axis.encoding.DeserializationContextImpl;
import org.apache.axis.encoding.DeserializationContext;
+import org.apache.axis.encoding.DeserializationContextImpl;
import org.apache.axis.test.AxisTestBase;
+import org.apache.axis.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
-import org.xml.sax.helpers.DefaultHandler;
-import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.soap.SOAPEnvelope;
import java.io.ByteArrayInputStream;
-import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PipedOutputStream;
@@ -345,9 +340,22 @@
parser2.getXMLReader().parse(inputsrc2);
}
+ // If we are using DeserializationContextImpl, we do not allow
+ // a DOCTYPE to be specified to prevent denial of service attacks
+ // via the ENTITY processing intstruction.
+ String msg2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<SOAP-ENV:Envelope " +
+ "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
+ "xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" > " +
+ "<SOAP-ENV:Body>\n" +
+ "<echo:Echo xmlns:echo=\"EchoService\">\n" +
+ "<symbol>IBM</symbol>\n" +
+ "</echo:Echo>\n" +
+ "</SOAP-ENV:Body></SOAP-ENV:Envelope>\n";
+
public void testSAXXXE3() throws Exception
{
- StringReader strReader3 = new StringReader(msg);
+ StringReader strReader3 = new StringReader(msg2);
DeserializationContext dser = new DeserializationContextImpl(
new InputSource(strReader3), null, org.apache.axis.Message.REQUEST);
dser.parse();
1.70 +17 -3
xml-axis/java/src/org/apache/axis/encoding/DeserializationContextImpl.java
Index: DeserializationContextImpl.java
===================================================================
RCS file:
/home/cvs/xml-axis/java/src/org/apache/axis/encoding/DeserializationContextImpl.java,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- DeserializationContextImpl.java 4 Nov 2002 16:19:58 -0000 1.69
+++ DeserializationContextImpl.java 19 Nov 2002 18:48:58 -0000 1.70
@@ -90,7 +90,6 @@
import javax.xml.rpc.JAXRPCException;
import java.io.IOException;
-import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashMap;
@@ -484,7 +483,7 @@
* @return TypeMapping or null
*/
public TypeMappingRegistry getTypeMappingRegistry() {
- return (TypeMappingRegistry) msgContext.getTypeMappingRegistry();
+ return msgContext.getTypeMappingRegistry();
}
/**
@@ -1020,8 +1019,23 @@
java.lang.String systemId)
throws SAXException
{
- if (recorder != null)
+ /* It is possible for a malicious user to send us bad stuff in
+ the <!DOCTYPE ../> tag that will cause a denial of service
+ Example:
+ <?xml version="1.0" ?>
+ <!DOCTYPE foobar [
+ <!ENTITY x0 "hello">
+ <!ENTITY x1 "&x0;&x0;">
+ <!ENTITY x2 "&x1;&x1;">
+ ...
+ <!ENTITY x99 "&x98;&x98;">
+ <!ENTITY x100 "&x99;&x99;">
+ ]>
+ */
+ throw new SAXException(Messages.getMessage("noInstructions00"));
+ /* if (recorder != null)
recorder.startDTD(name, publicId, systemId);
+ */
}
public void endDTD()