From 9ece6683b131a3f8b415cba3a781aea2c52b6cf6 Mon Sep 17 00:00:00 2001 From: David Cook Date: Thu, 23 May 2019 16:53:57 +1000 Subject: [PATCH] Bug 23290: XSLT system preferences allow administrators to exploit XML and XSLT vulnerabilities Content-Type: text/plain; charset=utf-8 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 --- Koha/XSLT_Handler.pm | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Koha/XSLT_Handler.pm b/Koha/XSLT_Handler.pm index 5b0726fddf..a4a0d0eaf9 100644 --- a/Koha/XSLT_Handler.pm +++ b/Koha/XSLT_Handler.pm @@ -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. + # + # breached! + # + 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. + 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 ($@) { -- 2.11.0