You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by jo...@apache.org on 2009/06/03 17:38:19 UTC

svn commit: r781437 - in /apr/apr-util/branches/0.9.x: CHANGES xml/apr_xml.c

Author: jorton
Date: Wed Jun  3 15:38:19 2009
New Revision: 781437

URL: http://svn.apache.org/viewvc?rev=781437&view=rev
Log:
Merge r781403 from APR trunk:

Prevent "billion laughs" attack against expat:

* xml/apr_xml.c (entity_declaration, default_handler): Add new handlers
  for expat 2.x and 1.x respectively.
  (apr_xml_parser_create): Install handler to prevent expansion of
  internal entities with expat 1.x, and to fail on an entity
  declaration with expat 2.x.


Modified:
    apr/apr-util/branches/0.9.x/CHANGES
    apr/apr-util/branches/0.9.x/xml/apr_xml.c

Modified: apr/apr-util/branches/0.9.x/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/0.9.x/CHANGES?rev=781437&r1=781436&r2=781437&view=diff
==============================================================================
--- apr/apr-util/branches/0.9.x/CHANGES [utf-8] (original)
+++ apr/apr-util/branches/0.9.x/CHANGES [utf-8] Wed Jun  3 15:38:19 2009
@@ -1,7 +1,10 @@
                                                      -*- coding: utf-8 -*-
 Changes with APR-util 0.9.17
 
-
+  *) SECURITY:
+     Fix a denial of service attack against the apr_xml_* interface
+     using the "billion laughs" entity expansion technique.
+     [Joe Orton]
 
 Changes with APR-util 0.9.16
 

Modified: apr/apr-util/branches/0.9.x/xml/apr_xml.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/0.9.x/xml/apr_xml.c?rev=781437&r1=781436&r2=781437&view=diff
==============================================================================
--- apr/apr-util/branches/0.9.x/xml/apr_xml.c (original)
+++ apr/apr-util/branches/0.9.x/xml/apr_xml.c Wed Jun  3 15:38:19 2009
@@ -339,6 +339,25 @@
     return APR_SUCCESS;
 }
 
+#if XML_MAJOR_VERSION > 1
+/* Stop the parser if an entity declaration is hit. */
+static void entity_declaration(void *userData, const XML_Char *entityName,
+                               int is_parameter_entity, const XML_Char *value,
+                               int value_length, const XML_Char *base,
+                               const XML_Char *systemId, const XML_Char *publicId,
+                               const XML_Char *notationName)
+{
+    apr_xml_parser *parser = userData;
+
+    XML_StopParser(parser->xp, XML_FALSE);
+}
+#else
+/* A noop default_handler. */
+static void default_handler(void *userData, const XML_Char *s, int len)
+{
+}
+#endif
+
 APU_DECLARE(apr_xml_parser *) apr_xml_parser_create(apr_pool_t *pool)
 {
     apr_xml_parser *parser = apr_pcalloc(pool, sizeof(*parser));
@@ -364,6 +383,19 @@
     XML_SetElementHandler(parser->xp, start_handler, end_handler);
     XML_SetCharacterDataHandler(parser->xp, cdata_handler);
 
+    /* Prevent the "billion laughs" attack against expat by disabling
+     * internal entity expansion.  With 2.x, forcibly stop the parser
+     * if an entity is declared - this is safer and a more obvious
+     * failure mode.  With older versions, installing a noop
+     * DefaultHandler means that internal entities will be expanded as
+     * the empty string, which is also sufficient to prevent the
+     * attack. */
+#if XML_MAJOR_VERSION > 1
+    XML_SetEntityDeclHandler(parser->xp, entity_declaration);
+#else
+    XML_SetDefaultHandler(parser->xp, default_handler);
+#endif
+
     return parser;
 }