Skip to content

Commit

Permalink
restrict XSLT read/write access to source and site directory
Browse files Browse the repository at this point in the history
  • Loading branch information
xworld21 committed Mar 4, 2023
1 parent ddc4d46 commit f7d837e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/LaTeXML/Common/XML/XSLT.pm
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,9 @@ sub transform {
my ($self, $document, %params) = @_;
return $$self{stylesheet}->transform($document, %params); }

sub security_callbacks {
my ($self, $security) = @_;
return $$self{stylesheet}->security_callbacks($security); }

#======================================================================
1;
26 changes: 26 additions & 0 deletions lib/LaTeXML/Post/XSLT.pm
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,32 @@ sub process {
my $orig_cwd = pathname_cwd();
pathname_chdir($destdir);

# restrict access so that the stylesheet can not:
# - write outside of the site directory (with <exsl:document>)
# - read outside of the source and site directories (with document())
# - access the network (with document())
my $sourcedir = $doc->getSourceDirectory;
my $sitedir = $doc->getSiteDirectory;
my $cb_write = sub {
my $dest = pathname_canonical(pathname_absolute($_[1], $destdir));
if (!pathname_is_contained($dest, $sitedir)) {
Fatal('unexpected', 'stylesheet', $doc, "denied write access to '$dest' outside of site directory '$sitedir'");
return 0; }
else { return 1; } };
my $cb_read = sub {
my $dest = pathname_canonical(pathname_absolute($_[1], $destdir));
if (!pathname_is_contained($dest, $sourcedir) && !pathname_is_contained($dest, $sitedir)) {
Fatal('unexpected', 'stylesheet', $doc, "denied read access to '$dest' outside of source directory '$sourcedir' and site directory '$sitedir'");
return 0; }
else { return 1; } };
my $security = XML::LibXSLT::Security->new;
$security->register_callback(read_file => $cb_read);
$security->register_callback(write_file => $cb_write);
$security->register_callback(create_dir => $cb_write);
$security->register_callback(read_net => sub { return 0; });
$security->register_callback(write_net => sub { return 0; });
$$self{stylesheet}->security_callbacks($security);

my $newdoc = $doc->new($$self{stylesheet}->transform($doc->getDocument, %params));

pathname_chdir($orig_cwd);
Expand Down

0 comments on commit f7d837e

Please sign in to comment.