diff -ruN a/cgi/ajax/phrase b/cgi/ajax/phrase
--- a/cgi/ajax/phrase	2021-02-10 19:32:36.627548294 +0000
+++ b/cgi/ajax/phrase	2021-02-10 19:48:11.606327919 +0000
@@ -36,7 +36,7 @@
 	{
 		for(values(%$pins))
 		{
-			my $doc = eval { $repo->xml->parse_string( $_ ) };
+			my $doc = eval { $repo->xml->parse_string( $_, expand_entities => 0 ) };
 			if( defined $doc )
 			{
 				$_ = $repo->xml->clone( $doc->documentElement );
diff -ruN a/cgi/cal b/cgi/cal
--- a/cgi/cal	2021-02-10 19:32:36.627548294 +0000
+++ b/cgi/cal	2021-02-10 19:48:11.607327929 +0000
@@ -15,6 +15,23 @@
 my $content = "text/html";
 $session->send_http_header( content_type=>$content );
 
+my @params = $session->param;
+for ( @params )
+{
+	unless ( $_ =~ m/^[a-z]+$/ ) 
+	{
+		my $message = "Invalid parameter name";
+                EPrints::Apache::AnApache::send_status_line( $session->{"request"}, 422, $message );
+		exit( 0 );
+	}
+	unless ( $session->param( $_ ) =~ m/^[0-9]+$/ ) 
+	{
+		my $message = "Invalid value for parameter '".$_."'";
+		EPrints::Apache::AnApache::send_status_line( $session->{"request"}, 422, $message );
+		exit( 0 );
+	}
+}
+
 my($nday, $nmonth, $nyear)=(localtime)[3,4,5];
 my $today = sprintf("%04d_%02d_%02d", ($nyear+1900), ($nmonth+1), $nday);
 
diff -ruN a/cgi/dataset_dictionary b/cgi/dataset_dictionary
--- a/cgi/dataset_dictionary	2021-02-10 19:32:36.627548294 +0000
+++ b/cgi/dataset_dictionary	2021-02-10 19:48:11.607327929 +0000
@@ -6,10 +6,17 @@
 $session->send_http_header( content_type=>$content );
 
 my $dataset = $session->param( "dataset" );
-   $dataset = "eprint" unless $dataset;
+$dataset = "eprint" unless $dataset;
+if ( $dataset !~ m/^[a-zA-Z0-9_]+$/ || !defined $session->dataset( $dataset ) )
+{
+	my $message = "Specified dataset does not exist";
+	EPrints::Apache::AnApache::send_status_line( $session->{"request"}, 422, $message );
+	exit( 0 );
+} 
 
 my $nohead = $session->param( "nohead" );
-   $nohead = 0 unless $nohead;
+$nohead = 0 unless $nohead;
+$nohead = 1 if $nohead;
 
 if( !( $session->current_user && $session->current_user->value("usertype") =~ /^(admin|local_admin)$/ ) )
 {
diff -ruN a/cgi/history_search b/cgi/history_search
--- a/cgi/history_search	2021-02-10 19:32:36.627548294 +0000
+++ b/cgi/history_search	2021-02-10 19:48:11.608327939 +0000
@@ -29,6 +29,27 @@
 #get end date
 my $end_date = $session->param( "end_date" );
 
+
+# Validation against XSS
+if ( EPrints::Utils::is_set( $fname ) && $fname !~ m/^[a-zA-Z0-9_]+$/ )
+{
+        my $message = "Specified field name is not valid";
+        EPrints::Apache::AnApache::send_status_line( $session->{"request"}, 422, $message );
+        exit( 0 );
+}
+if ( EPrints::Utils::is_set( $start_date ) && $start_date !~ m/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/ )
+{
+	my $message = "Specified start date is not valid";
+        EPrints::Apache::AnApache::send_status_line( $session->{"request"}, 422, $message );
+        exit( 0 );
+}
+if ( EPrints::Utils::is_set( $end_date ) && $end_date !~ m/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/ )
+{
+        my $message = "Specified end date is not valid";
+        EPrints::Apache::AnApache::send_status_line( $session->{"request"}, 422, $message );
+        exit( 0 );
+}
+
 #title
 my $title = $session->make_element( "h2" );
 $title->appendChild( $session->make_text( "History Search" ) );
diff -ruN a/cgi/latex2png b/cgi/latex2png
--- a/cgi/latex2png	2021-02-10 19:32:36.627548294 +0000
+++ b/cgi/latex2png	1970-01-01 00:00:00.000000000 +0000
@@ -1,50 +0,0 @@
-######################################################################
-#
-#  Turn a latex string into a PNG
-#
-######################################################################
-#
-#  __COPYRIGHT__
-#
-# Copyright 2020 University of Southampton.
-# EPrints 3.4 is supplied by EPrints Services.
-#
-# http://www.eprints.org/eprints-3.4/
-#
-#  __LICENSE__
-#
-# This file is part of EPrints 3.4 L<http://www.eprints.org/>.
-#
-# EPrints 3.4 and this file are released under the terms of the
-# GNU Lesser General Public License version 3 as published by
-# the Free Software Foundation unless otherwise stated.
-#
-# EPrints 3.4 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with EPrints 3.4.
-# If not, see L<http://www.gnu.org/licenses/>.
-#
-######################################################################
-
-use EPrints;
-
-use strict;
-
-my $session = new EPrints::Session;
-exit( 0 ) unless( defined $session );
-
-my $latex = $session->param( "latex" );
-$latex = "???" if( !defined $latex );
-
-my $pngfile = EPrints::Latex::texstring_to_png( $session, $latex );
-
-$session->send_http_header( content_type=>'image/png' );
-open( PNG, $pngfile ) || die "can't open $pngfile";
-while(<PNG>) { print; }
-close PNG;
-
-$session->terminate();
diff -ruN a/cgi/toolbox/toolbox b/cgi/toolbox/toolbox
--- a/cgi/toolbox/toolbox	2021-02-10 19:32:36.628548304 +0000
+++ b/cgi/toolbox/toolbox	2021-02-10 19:48:11.610327960 +0000
@@ -43,6 +43,11 @@
 
 my %opts = ();
 
+if ( $cmd !~ m/^[a-zA-Z0-9_]+$/ )
+{
+	toolbox_fail( $session, "Invalid toolbox function" );
+}
+
 if( !$session->valid_login( $username, $password ) )
 {
 	toolbox_fail( $session, "Invalid username/password" );
diff -ruN a/lib/syscfg.d/invocations.pl b/lib/syscfg.d/invocations.pl
--- a/lib/syscfg.d/invocations.pl	2021-02-10 19:32:36.628548304 +0000
+++ b/lib/syscfg.d/invocations.pl	2021-02-10 19:48:11.731329226 +0000
@@ -6,7 +6,7 @@
 	 'dvips' => '$(dvips) $(SOURCE) -o $(TARGET)',
 	 'sendmail' => '$(sendmail) -oi -t -odb --',
 	 'elinks' => '$(elinks) -dump 1 -dump-charset UTF-8 $(SOURCE) > $(TARGET)',
-	 'latex' => '$(latex) $(SOURCE)',
+	 'latex' => '$(latex) -no-shell-escape -output-directory=$(TARGET) $(SOURCE)',
 	 'targz' => '$(gunzip) -c < $(ARC) 2>/dev/null | $(tar) xf - -C $(DIR) >/dev/null 2>&1',
 	 'antiwordpdf' => '$(antiword) -a a4 -m 8859-1 $(SOURCE) > $(TARGET)',
 	 'pdftotext' => '$(pdftotext) -enc UTF-8 -layout $(SOURCE) $(TARGET)',
diff -ruN a/lib/workflows/saved_search/default.xml b/lib/workflows/saved_search/default.xml
--- a/lib/workflows/saved_search/default.xml	2021-02-10 19:32:36.628548304 +0000
+++ b/lib/workflows/saved_search/default.xml	2021-02-10 19:48:11.739329309 +0000
@@ -12,7 +12,7 @@
     <component><field ref="name"/></component>
 
     <!-- see https://github.com/eprints/eprints/issues/169 - can be removed when this issue fixed -->
-    <epc:if test="substr(spec.as_string(),0,30) = '?plugin=Xapian&amp;searchid=simple'">
+    <epc:if test="substr(spec.as_string(),0,30) = '?plugin=Xapian&amp;searchid=simple' or substr(spec.as_string(),0,33) = '?plugin=Xapianv2&amp;searchid=simple2'">
       <component type="XHTML"><epc:phrase ref="saved_search_xapian_warning"/></component>
     </epc:if>
 
diff -ruN a/perl_lib/EPrints/Latex.pm b/perl_lib/EPrints/Latex.pm
--- a/perl_lib/EPrints/Latex.pm	2021-02-10 19:32:36.628548304 +0000
+++ b/perl_lib/EPrints/Latex.pm	2021-02-10 19:48:11.754329466 +0000
@@ -273,7 +273,7 @@
 END
 	close TEX;
 
-	$repository->exec( "latex", SOURCE=>"$fbase.tex" );
+	$repository->exec( "latex", SOURCE=>"$fbase.tex", TARGET=>$cachedir );
 	$repository->exec( "dvips", SOURCE=>"$fbase.dvi", TARGET=>"$fbase.ps" );
 	$repository->exec( 
 		"convert_crop_white", 
@@ -284,14 +284,13 @@
 		"$fbase.dvi", 
 		"$fbase.tex", 
 		"$fbase.ps", 
-		"$fbase.log" );
+		"$fbase.log" 
+	);
 
 	chdir( $prev_dir );
 	return $ofile;
 }
 
-
-	
 1;
 
 ######################################################################
diff -ruN a/perl_lib/EPrints/XML/LibXML.pm b/perl_lib/EPrints/XML/LibXML.pm
--- a/perl_lib/EPrints/XML/LibXML.pm	2021-02-10 19:32:36.629548315 +0000
+++ b/perl_lib/EPrints/XML/LibXML.pm	2021-02-10 19:48:11.797329916 +0000
@@ -73,7 +73,7 @@
 	$PARSER = XML::LibXML->new( expand_entities=>1, load_external_dtd=>1 );
 }
 
-=item $doc = parse_xml_string( $string )
+=item $doc = parse_xml_string( $string, %opts )
 
 Create a new DOM document from $string.
 
@@ -81,8 +81,23 @@
 
 sub parse_xml_string
 {
-	my( $string ) = @_;
+	my( $string, %opts ) = @_;
 
+	if ( keys %opts )
+	{
+		my %cur_opts = ();
+		foreach ( keys %opts )
+		{
+			$cur_opts{$_} = $PARSER->get_option( $_ );
+			$PARSER->set_option( $_, $opts{$_} );
+		}
+		my $parsed = $PARSER->parse_string( $string );	
+		foreach ( keys %cur_opts )
+		{
+			$PARSER->set_option( $_, $cur_opts{$_} );
+		}
+		return $parsed;
+	}
 	return $PARSER->parse_string( $string );
 }
 
diff -ruN a/perl_lib/EPrints/XML.pm b/perl_lib/EPrints/XML.pm
--- a/perl_lib/EPrints/XML.pm	2021-02-10 19:32:36.628548304 +0000
+++ b/perl_lib/EPrints/XML.pm	2021-02-10 19:48:11.796329905 +0000
@@ -127,8 +127,8 @@
 
 sub parse_string
 {
-	my( $self, $string ) = @_;
-	return parse_xml_string( $string );
+	my( $self, $string, %opts ) = @_;
+	return parse_xml_string( $string, %opts );
 }
 
 =item $doc = $xml->parse_file( $filename, %opts )
