[tex-live] Status of restricted \write18 and epstopdf conversion
Alexander Cherepanov
cherepan at mccme.ru
Sun Oct 18 00:57:37 CEST 2009
Hi Manuel!
On Thu, 15 Oct 2009 23:55:16 +0200, Manuel Pégourié-Gonnard <mpg at elzevir.fr> wrote:
> repstopdf, which has been specially crafted for
> this purpose: all options are checked to avoid injection, so the only
> external program called is ghostscript with -dSAFER,
First of all, you talk about
rsync://tug.org/tldevsrc/Master/texmf-dist/scripts/epstopdf/epstopdf.pl
(size: 17776, last changed: 2009/10/15 03:39:50), right?
As far as I can see, there are no checks for injections in --outfile=
at all. Arbitrary command execution is possible:
./repstopdf --outfile='out.pdf" - -c quit; echo Hi! > out; true "' input.eps
This should be prohibited, I suppose?
The following should be prohibited as well:
./repstopdf --gscmd="gs
" input.eps
./repstopdf --autorotate="None
" input.eps
> and the output file
> name is subject to conditions more restrictive than openout_any=p (it
> was easier than to implement a true support of this variable).
There is a couple of quirks on Windows. Relative paths on other
drives (like "c:dir/file") are allowed. And alternate data streams
on NTFS (like "file:ads") are allowed (didn't test it but should work;
no big deal in a any case but to be on a safe side it's better to ban
it). Both could be ruled out by checking for a colon.
And you can use backslash as a path separator on cygwin:
./repstopdf --outfile='dir\..\..\..\out.pdf' input.eps
(tested on cygwin1.5 only).
Approximate patch:
--- epstopdf.pl.orig 2009-10-15 03:39:50.000000000 +0400
+++ epstopdf.pl 2009-10-18 02:50:24.000000000 +0400
@@ -277,7 +277,7 @@
# \label{val_autorotate}
die "Invalid value for autorotate: '$::opt_autorotate' (use 'All', 'None' or 'PageByPage').\n"
if ($::opt_autorotate and
- not $::opt_autorotate =~ /^(None|All|PageByPage)$/);
+ not $::opt_autorotate =~ /^(None|All|PageByPage)\z/);
### option BoundingBox types
my $BBName = "%%BoundingBox:";
@@ -320,10 +320,20 @@
my ($drive, $path, $basename) = splitpath($OutputFilename);
$ok = 0 if $basename =~ /^\./;
}
+ # disallow colon on Windows. It could be used either after a drive
+ # (like "a:dir\file") or for an alternate data stream (like
+ # "file:ads").
+ if ($^O eq "MSWin32" || $^O eq "cygwin") {
+ $ok = 0 if $OutputFilename =~ /:/;
+ }
+ # disallow quote
+ $ok = 0 if $OutputFilename =~ /"/;
+ # disallow newline (just to be on a safe side)
+ $ok = 0 if $OutputFilename =~ /\n/;
# disallow absolute path
$ok = 0 if file_name_is_absolute($OutputFilename);
# disallow going to parent directory
- my $ds = ($^O eq "MSWin32") ? qr([\\/]) : qr(/);
+ my $ds = ($^O eq "MSWin32" || $^O eq "cygwin") ? qr([\\/]) : qr(/);
$ok = 0 if $OutputFilename =~ /^\.\.$ds|$ds\.\.$ds/;
# we passed all tests
die error "Output filename '$OutputFilename' not allowed in restricted mode." unless $ok;
@@ -335,8 +345,8 @@
$GS = $::opt_gscmd;
# validate GS \label{val_gscmd}
if ($restricted) {
- $GS =~ /^(gs|mgs|gswin32c|gs386|gsos2)$/
- or $GS =~ /^gs[\-_]?(\d|\d[\.-_]?\d\d)c?$/
+ $GS =~ /^(gs|mgs|gswin32c|gs386|gsos2)\z/
+ or $GS =~ /^gs[\-_]?(\d|\d[\.-_]?\d\d)c?\z/
or die error "Value of gscmd '$GS' not allowed in restricted mode.";
}
}
It should be tested more thoroughly (at least at cygwin1.7) but I want
to get it out earlier.
Alexander Cherepanov
More information about the tex-live
mailing list