From 61189ecca9947870c1d6e7186197b3776170224f Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Fri, 28 Jan 2022 12:45:12 -0800 Subject: [PATCH] Helper/Nix: constructRunCommandLogPath: verify uuid is valid This shouldn't be possible normally, but it is possible to: $db->resultset('RunCommandLogs')->new({ uuid => "../etc/passwd" }); if you have access to the `$db`. --- src/lib/Hydra/Controller/Root.pm | 6 ++++-- src/lib/Hydra/Helper/Nix.pm | 16 ++++++++-------- t/Hydra/Helper/Nix.t | 6 ++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/lib/Hydra/Controller/Root.pm b/src/lib/Hydra/Controller/Root.pm index 247a6caf..c6843d29 100644 --- a/src/lib/Hydra/Controller/Root.pm +++ b/src/lib/Hydra/Controller/Root.pm @@ -537,8 +537,10 @@ sub runcommandlog :Local :Args(1) { die if defined $tail && $tail !~ /^[0-9]+$/; - my $runlog = $c->model('DB')->resultset('RunCommandLogs')->find({ uuid => $uuid }); - my $logFile = constructRunCommandLogPath($runlog) or notFound($c, "RunCommandLog not found."); + my $runlog = $c->model('DB')->resultset('RunCommandLogs')->find({ uuid => $uuid }) + or notFound($c, "The RunCommand log is not available."); + + my $logFile = constructRunCommandLogPath($runlog); if (-f $logFile) { serveLogFile($c, $logFile, $tail); return; diff --git a/src/lib/Hydra/Helper/Nix.pm b/src/lib/Hydra/Helper/Nix.pm index 9c804011..6f7852af 100644 --- a/src/lib/Hydra/Helper/Nix.pm +++ b/src/lib/Hydra/Helper/Nix.pm @@ -13,6 +13,7 @@ use Nix::Store; use Encode; use Sys::Hostname::Long; use IPC::Run; +use UUID4::Tiny qw(is_uuid4_string); our @ISA = qw(Exporter); our @EXPORT = qw( @@ -592,17 +593,16 @@ sub isLocalStore { sub constructRunCommandLogPath { my ($runlog) = @_; - my $path = undef; + my $uuid = $runlog->uuid; - eval { - my $uuid = $runlog->uuid; - my $hydra_path = Hydra::Model::DB::getHydraPath; - my $bucket = substr($uuid, 0, 2); + if (!is_uuid4_string($uuid)) { + die "UUID was invalid." + } - $path = "$hydra_path/runcommand-logs/$bucket/$uuid"; - }; + my $hydra_path = Hydra::Model::DB::getHydraPath; + my $bucket = substr($uuid, 0, 2); - return $path; + return "$hydra_path/runcommand-logs/$bucket/$uuid"; } 1; diff --git a/t/Hydra/Helper/Nix.t b/t/Hydra/Helper/Nix.t index 8abb60ea..a34cfe02 100644 --- a/t/Hydra/Helper/Nix.t +++ b/t/Hydra/Helper/Nix.t @@ -82,6 +82,12 @@ subtest "constructRunCommandLogPath" => sub { qr@/runcommand-logs/[0-9a-f]{2}/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}@, "The constructed RunCommandLog path is sufficiently bucketed and UUID-like." ); + + my $badlog = $db->resultset('RunCommandLogs')->new({ uuid => "../../../etc/passwd" }); + ok( + dies { Hydra::Helper::Nix::constructRunCommandLogPath($badlog) }, + "Expected invalid UUID to be rejected and not have a path constructed for it.", + ); }; done_testing;