@@ -, +, @@
---
t/db_dependent/Koha/XSLT/Security.t | 116 ++++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
create mode 100644 t/db_dependent/Koha/XSLT/Security.t
--- a/t/db_dependent/Koha/XSLT/Security.t
+++ a/t/db_dependent/Koha/XSLT/Security.t
@@ -0,0 +1,116 @@
+#!/usr/bin/perl
+
+# Copyright 2019 Rijksmuseum
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+use File::Temp qw/tempfile/;
+use Test::More tests => 6;
+use Test::Warn;
+
+use Koha::XSLT::Base;
+use t::lib::Mocks;
+
+t::lib::Mocks::mock_config( 'koha_xslt_security', { expand_entities => 1 } );
+my $engine=Koha::XSLT::Base->new;
+
+my $secret_file = mytempfile('Big secret');
+my $xslt=<<"EOT";
+]>
+
+
+ &secret;
+
+
+
+
+EOT
+my $xslt_file = mytempfile($xslt);
+
+my $output= $engine->transform( "", $xslt_file );
+like($output, qr/Big secret/, 'external entity got through');
+
+t::lib::Mocks::mock_config( 'koha_xslt_security', { expand_entities => 0 } );
+$engine=Koha::XSLT::Base->new;
+$output= $engine->transform( "", $xslt_file );
+unlike($output, qr/Big secret/, 'external entity did not get through');
+
+# Adding a document call to trigger callback for read_file
+# Does not depend on expand_entities.
+$xslt=<<"EOT";
+
+
+
+
+
+
+EOT
+$xslt_file = mytempfile($xslt);
+warning_like { $output= $engine->transform( "", $xslt_file ); }
+ qr/read_file called in XML::LibXSLT/,
+ 'Triggered security callback for read_file';
+
+# Trigger write_file
+$xslt=<<"EOT";
+
+
+
+ Breached!
+
+
+EOT
+$xslt_file = mytempfile($xslt);
+warning_like { $output= $engine->transform( "", $xslt_file ); }
+ qr/write_file called in XML::LibXSLT/,
+ 'Triggered security callback for write_file';
+
+# Trigger read_net
+$xslt=<<"EOT";
+
+
+
+
+
+
+EOT
+$xslt_file = mytempfile($xslt);
+warning_like { $output= $engine->transform( "", $xslt_file ); }
+ qr/read_net called in XML::LibXSLT/,
+ 'Triggered security callback for read_net';
+
+# Check remote import (include should be similar)
+# Trusting koha-community.org DNS here ;)
+# This should not trigger read_net but fail on the missing import.
+$xslt=<<"EOT";
+
+
+
+
+
+EOT
+$xslt_file = mytempfile($xslt);
+$engine->print_warns(1);
+warning_like { $output= $engine->transform( "", $xslt_file ); }
+ qr/I\/O warning : failed to load external entity/,
+ 'Remote import does not fail on read_net';
+
+sub mytempfile {
+ my ( $fh, $fn ) = tempfile( SUFFIX => '.xsl', UNLINK => 1 );
+ print $fh $_[0]//'';
+ close $fh;
+ return $fn;
+}
--