CVE-2011-2206 (published 2011-06-22T22:55Z)

XMLParser.pm in DJabberd before 0.85 allows remote authenticated users to read arbitrary files, and possibly send HTTP requests to intranet servers or cause a denial of service (CPU and memory consumption), via an XML external entity declaration in conjunction with an entity reference, a different vulnerability than CVE-2011-1757.

Severity: MEDIUM
CVSS v2 base score: 5.5 (AV:N/AC:L/Au:S/C:P/I:N/A:P)

Weakness information:
cwe_id: CWE-399
cwe_name: Resource Management Errors
description: Weaknesses in this category are related to improper management of system resources.

Fix information:
repo_url: https://github.com/djabberd/DJabberd
commit_details: repo_url: https://github.com/djabberd/DJabberd
author: Yann Kerherve
author_date: 2011-06-05 11:27:42-07:00
msg: Fix XML Parser to fail on external entities

Bump dependency on LibXML to the latest because of their recent
new() signature change
repository: repo_url: https://github.com/djabberd/DJabberd
repo_name: djabberd/DJabberd
description: The main DJabberd source
repo_language: Perl
owner: djabberd
file_changes: filename: Makefile.PL
change_type: ModificationType.MODIFY
diff: @@ -9,6 +9,7 @@ WriteMakefile(
               PREREQ_PM    => {
                   'Danga::Socket'                => 1.51,
                   'XML::SAX'                     => 0,
+                  'XML::LibXML'                  => 1.70,
                   'XML::LibXML::SAX'             => 0,
                   'Net::DNS'                     => 0.48,
                   'Net::SSLeay'                  => 0,

programming_language: Perl
filename: XMLParser.pm
change_type: ModificationType.MODIFY
diff: @@ -16,7 +16,17 @@ sub new {
 
     # libxml mode:
     if (1) {
-        my $libxml = XML::LibXML->new;
+        my $libxml = XML::LibXML->new({
+            no_network => 1,
+            load_ext_dtd => 0,
+            expand_entities => 0,
+            expand_xinclude => 0,
+            ext_ent_handler => sub {
+                # my ($sys_id, $pub_id) = @_;
+                # warn "Received external entity: $sys_id:$pub_id";
+                "";
+            },
+        });
         $libxml->set_handler($self);
         $self->{LibParser} = $libxml;
 

programming_language: Perl
filename: v.txt
change_type: ModificationType.ADD
diff: @@ -0,0 +1 @@
+vuln

programming_language: SQL
filename: xmlparsing.t
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,7 @@ use XML::SAX;
 use DJabberd::XMLParser;
 use XML::SAX::PurePerl;
 use Scalar::Util qw(weaken);
-use Test::More tests => 10;
+use Test::More tests => 14;
 use Data::Dumper;
 
 my $fulldoc = qq{<?xml version="1.0"?><root xmlns='root' xmlns:a='aa' global='foo' xmlns:b='bb' a:name='aname' b:name='bname' name='globalname'>
@@ -43,7 +43,7 @@ ok(!$ref, "p went away");
 {
     my $handler = EventRecorder->new(\$dummy);
     my $p       = DJabberd::XMLParser->new(Handler => $handler);
-    $p->parse_more("<foo><tag>");
+    $p->parse_more("<foo>&lt;<tag>");
     $p->finish_push;
     like($dummy, qr/foo.+tag/s);
     $ref = \$p;
@@ -51,6 +51,41 @@ ok(!$ref, "p went away");
 }
 ok(!$ref, "p went away");
 
+## external entities are disabled
+{
+    use FindBin;
+    my $v = "$FindBin::Bin/v.txt";
+
+    my $xml1 = <<"EOF";
+<?xml version="1.0"?>
+<!DOCTYPE foo [
+<!ENTITY a PUBLIC "//foo" "file:$v">
+]>
+<root>
+  <a>&lt; A=&a;</a>
+</root>
+EOF
+    my $xml2 = <<"EOF";
+<?xml version="1.0"?>
+<!DOCTYPE foo [
+<!ENTITY b SYSTEM "file://$v">
+]>
+<root>
+  <b>B=&b;</b>
+</root>
+EOF
+    for ($xml1, $xml2) {
+        my $handler = EventRecorder->new(\$dummy);
+        my $p       = DJabberd::XMLParser->new(Handler => $handler);
+        eval {
+            $p->parse_more($_);
+            $p->finish_push;
+        };
+        ok $@, "died on unknown entity: $@";
+        unlike($dummy, qr/vuln/si);
+    }
+}
+
 # byte at a time
 my $n = 0;
 my $byte_events;
@@ -80,9 +115,14 @@ use Data::Dumper;
 sub new {
     my ($class, $outref) = @_;
     $$outref = "";
-    return bless {
-        outref => $outref,
-    };
+    my $self = $class->SUPER::new();
+    $self->{outref} = $outref;
+    return $self;
+}
+
+sub characters {
+    my ($self, $data) = @_;
+    ${ $self->{outref} } .= $data->{Data};
 }
 
 sub start_element {

programming_language: Perl