diff --git a/src/libexpr/primops/flake.cc b/src/libexpr/primops/flake.cc index 293e5ad0b..de692f167 100644 --- a/src/libexpr/primops/flake.cc +++ b/src/libexpr/primops/flake.cc @@ -285,7 +285,10 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe + "/" + flake.sourceInfo.rev->to_string(Base16, false)); } - Path flakeFile = sourceInfo.storePath + "/" + resolvedRef.subdir + "/flake.nix"; + // Guard against symlink attacks. + auto flakeFile = canonPath(sourceInfo.storePath + "/" + resolvedRef.subdir + "/flake.nix"); + if (!isInDir(flakeFile, sourceInfo.storePath)) + throw Error("flake file '%s' escapes from '%s'", resolvedRef, sourceInfo.storePath); if (!pathExists(flakeFile)) throw Error("source tree referenced by '%s' does not contain a '%s/flake.nix' file", resolvedRef, resolvedRef.subdir); diff --git a/src/libexpr/primops/flakeref.cc b/src/libexpr/primops/flakeref.cc index 56ba58d09..b7a20a170 100644 --- a/src/libexpr/primops/flakeref.cc +++ b/src/libexpr/primops/flakeref.cc @@ -107,7 +107,7 @@ FlakeRef::FlakeRef(const std::string & uri, bool allowRelative) throw Error("invalid Git ref '%s'", value); ref = value; } else if (name == "dir") { - if (!std::regex_match(value, subDirRegex2)) + if (value != "" && !std::regex_match(value, subDirRegex2)) throw Error("flake '%s' has invalid subdirectory '%s'", uri, value); subdir = value; } else