From 26c170b4e309542685a9cf9b8d5bdee6cd1d6c7c 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 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 Signed-off-by: Martin Renvoize --- 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.20.1