diff options
-rwxr-xr-x | webserver | 10 |
1 files changed, 4 insertions, 6 deletions
@@ -38,6 +38,7 @@ use warnings; # not a problem since FD can be bound as root prior to the execve(2). use Errno 'EINTR'; +use Fcntl qw/O_NOFOLLOW O_RDONLY/; use Socket qw/AF_UNIX AF_INET AF_INET6/; # Untaint and fdopen(3) the listening socket @@ -91,12 +92,9 @@ while (1) { while (defined (my $h = $conn->getline())) { last if $h eq "\r\n" }; my ($status_line, $content_type, $content); - if ($req =~ /\A\Q$ROOT\E\/([A-Za-z0-9_\-]+)\z/ and - ! -l $1 and -f _) { # reuse previous stat structure and save a syscall - # XXX calling lstat(2) before open(2) is racy; if O_NOFOLLOW was - # exposed to perl we would instead use it and later fstat(2) the - # file descriptor - if (open my $fh, '<', $1) { # only open files in the cwd + if ($req =~ /\A\Q$ROOT\E\/([A-Za-z0-9_\-]+)\z/ and -f $1) { + # only open files in the cwd, and refuse to follow symlinks + if (sysopen(my $fh, $1, O_NOFOLLOW|O_RDONLY)) { ($status_line, $content_type) = ('200 OK', 'application/jose+json'); $content = do { local $/ = undef; $fh->getline() }; $fh->close() or die "close: $!"; |