apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bo...@apache.org
Subject svn commit: r783589 - in /apr/apr-util/branches/1.4.x: ./ CHANGES buckets/apr_brigade.c test/data/billion-laughs.xml test/testxml.c xml/apr_xml.c
Date Thu, 11 Jun 2009 00:22:09 GMT
Author: bojan
Date: Thu Jun 11 00:22:09 2009
New Revision: 783589

URL: http://svn.apache.org/viewvc?rev=783589&view=rev
Log:
Backport r781403 from the 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.

* test/testxml.c (create_dummy_file, dump_xml): Test that predefined
  entities are expanded.
  (test_billion_laughs): New test case.

Added:
    apr/apr-util/branches/1.4.x/test/data/billion-laughs.xml
      - copied unchanged from r781403, apr/apr/trunk/test/data/billion-laughs.xml
Modified:
    apr/apr-util/branches/1.4.x/   (props changed)
    apr/apr-util/branches/1.4.x/CHANGES
    apr/apr-util/branches/1.4.x/buckets/apr_brigade.c   (props changed)
    apr/apr-util/branches/1.4.x/test/testxml.c
    apr/apr-util/branches/1.4.x/xml/apr_xml.c

Propchange: apr/apr-util/branches/1.4.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Jun 11 00:22:09 2009
@@ -1 +1,2 @@
+/apr/apr/trunk:781403
 /apr/apr-util/trunk:731033-731034,731225,731236,731291,731293,731379,743986,744009,745771,747612,747623,747630

Modified: apr/apr-util/branches/1.4.x/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/CHANGES?rev=783589&r1=783588&r2=783589&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/CHANGES [utf-8] (original)
+++ apr/apr-util/branches/1.4.x/CHANGES [utf-8] Thu Jun 11 00:22:09 2009
@@ -1,6 +1,11 @@
                                                      -*- coding: utf-8 -*-
 Changes with APR-util 1.4.0
 
+  *) SECURITY:
+     Fix a denial of service attack against the apr_xml_* interface
+     using the "billion laughs" entity expansion technique.
+     [Joe Orton]
+
   *) Fix race conditions in initialisation of DBD, DBM and DSO.
      [Bojan Smojver]
 

Propchange: apr/apr-util/branches/1.4.x/buckets/apr_brigade.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Jun 11 00:22:09 2009
@@ -1,2 +1,2 @@
-/apr/apr/trunk/buckets/apr_brigade.c:768417
+/apr/apr/trunk/buckets/apr_brigade.c:768417,781403
 /apr/apr-util/trunk/buckets/apr_brigade.c:731033-731034,731225,731236,731291,731293,731379,743986,744009,745771,747612,747623,747630

Modified: apr/apr-util/branches/1.4.x/test/testxml.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/test/testxml.c?rev=783589&r1=783588&r2=783589&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/test/testxml.c (original)
+++ apr/apr-util/branches/1.4.x/test/testxml.c Thu Jun 11 00:22:09 2009
@@ -36,8 +36,7 @@
         return rv;
 
     rv = apr_file_puts("<?xml version=\"1.0\" ?>\n<maryx>"
-                       "<had a=\"little\"/><lamb its='fleece "
-                       "was white as snow' />\n", *fd);
+                       "<had a=\"little\"/><lamb/>\n", *fd);
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
     for (i = 0; i < 5000; i++) {
@@ -75,7 +74,7 @@
 
     for (i = 0; i < 5000; i++) {
         rv = apr_file_puts("<hmm roast=\"lamb\" "
-                           "for=\"dinner\">yummy</hmm>\n", *fd);
+                           "for=\"dinner &lt;&gt;&#x3D;\">yummy</hmm>\n",
*fd);
         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
     }
 
@@ -103,7 +102,7 @@
         a = e->attr;
         ABTS_PTR_NOTNULL(tc, a);
         ABTS_STR_EQUAL(tc, "for", a->name);
-        ABTS_STR_EQUAL(tc, "dinner", a->value);
+        ABTS_STR_EQUAL(tc, "dinner <>=", a->value);
         a = a->next;
         ABTS_PTR_NOTNULL(tc, a);
         ABTS_STR_EQUAL(tc, "roast", a->name);
@@ -149,11 +148,29 @@
     ABTS_TRUE(tc, rv != APR_SUCCESS);
 }
 
+static void test_billion_laughs(abts_case *tc, void *data)
+{
+    apr_file_t *fd;
+    apr_xml_parser *parser;
+    apr_xml_doc *doc;
+    apr_status_t rv;
+
+    rv = apr_file_open(&fd, "billion-laughs.xml", 
+                       APR_FOPEN_READ, 0, p);
+    apr_assert_success(tc, "open billion-laughs.xml", rv);
+
+    rv = apr_xml_parse_file(p, &parser, &doc, fd, 2000);
+    ABTS_TRUE(tc, rv != APR_SUCCESS);
+
+    apr_file_close(fd);
+}
+
 abts_suite *testxml(abts_suite *suite)
 {
     suite = ADD_SUITE(suite);
 
     abts_run_test(suite, test_xml_parser, NULL);
+    abts_run_test(suite, test_billion_laughs, NULL);
 
     return suite;
 }

Modified: apr/apr-util/branches/1.4.x/xml/apr_xml.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/xml/apr_xml.c?rev=783589&r1=783588&r2=783589&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/xml/apr_xml.c (original)
+++ apr/apr-util/branches/1.4.x/xml/apr_xml.c Thu Jun 11 00:22:09 2009
@@ -347,6 +347,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));
@@ -372,6 +391,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;
 }
 



Mime
View raw message