Bug 23290: XSLT system preferences allow administrators to exploit XML and XSLT vulnerabilities

The problem is that administrators can provide XSLTs that
can read from the server and network and write to the server. The

This patch prevents the Koha::XSLT_Handler from running
XSLT stylesheets that call actions such as read_file, write_file,
read_net, and write_net as documented at
https://metacpan.org/pod/XML::LibXSLT#XML::LibXSLT::Security

(Previous tests suggested issues with XML external entities
causing read file like vulnerabilities but these were not
reproducible)

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
This commit is contained in:
David Cook 2019-05-23 16:53:57 +10:00 committed by Martin Renvoize
parent 884ab0d98e
commit 322fbf151b
No known key found for this signature in database
GPG Key ID: 422B469130441A0F
1 changed files with 33 additions and 0 deletions

View File

@ -318,8 +318,41 @@ sub _load {
return;
}
my $security = XML::LibXSLT::Security->new();
$security->register_callback( read_file => sub {
warn "read_file called in XML::LibXSLT";
#i.e. when using the exsl:document() element or document() function (to read a XML file)
my ($tctxt,$value) = @_;
return 0;
});
$security->register_callback( write_file => sub {
warn "write_file called in XML::LibXSLT";
#i.e. when using the exsl:document element (or document() function?) (to write an output file of many possible types)
#e.g.
#<exsl:document href="file:///tmp/breached.txt">
# <xsl:text>breached!</xsl:text>
#</exsl:document>
my ($tctxt,$value) = @_;
return 0;
});
$security->register_callback( read_net => sub {
warn "read_net called in XML::LibXSLT";
#i.e. when using the document() function (to read XML from the network)
#e.g. <xsl:copy-of select="document('http://localhost')" />
my ($tctxt,$value) = @_;
return 0;
});
$security->register_callback( write_net => sub {
warn "write_net called in XML::LibXSLT";
#NOTE: it's unknown how one would invoke this, but covering our bases anyway
my ($tctxt,$value) = @_;
return 0;
});
#parse sheet
my $xslt = XML::LibXSLT->new;
$xslt->security_callbacks( $security );
$rv = $code? $digest.$codelen: $filename;
$self->{xslt_hash}->{$rv} = eval { $xslt->parse_stylesheet($style_doc) };
if ($@) {