mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-22 14:06:16 +02:00
allowed-uris: Match whole schemes also when scheme is not followed by slashes
This commit is contained in:
parent
d3a85b6834
commit
a05bc9eb92
4 changed files with 63 additions and 1 deletions
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
synopsis: Option `allowed-uris` can now match whole schemes in URIs without slashes
|
||||||
|
prs: 9547
|
||||||
|
---
|
||||||
|
|
||||||
|
If a scheme, such as `github:` is specified in the `allowed-uris` option, all URIs starting with `github:` are allowed.
|
||||||
|
Previously this only worked for schemes whose URIs used the `://` syntax.
|
|
@ -68,6 +68,11 @@ struct EvalSettings : Config
|
||||||
evaluation mode. For example, when set to
|
evaluation mode. For example, when set to
|
||||||
`https://github.com/NixOS`, builtin functions such as `fetchGit` are
|
`https://github.com/NixOS`, builtin functions such as `fetchGit` are
|
||||||
allowed to access `https://github.com/NixOS/patchelf.git`.
|
allowed to access `https://github.com/NixOS/patchelf.git`.
|
||||||
|
|
||||||
|
Access is granted when
|
||||||
|
- the URI is equal to the prefix,
|
||||||
|
- or the URI is a subpath of the prefix,
|
||||||
|
- or the prefix is a URI scheme ended by a colon `:` and the URI has the same scheme.
|
||||||
)"};
|
)"};
|
||||||
|
|
||||||
Setting<bool> traceFunctionCalls{this, false, "trace-function-calls",
|
Setting<bool> traceFunctionCalls{this, false, "trace-function-calls",
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "memory-input-accessor.hh"
|
#include "memory-input-accessor.hh"
|
||||||
#include "signals.hh"
|
#include "signals.hh"
|
||||||
#include "gc-small-vector.hh"
|
#include "gc-small-vector.hh"
|
||||||
|
#include "url.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
@ -599,6 +600,14 @@ void EvalState::allowAndSetStorePathString(const StorePath & storePath, Value &
|
||||||
mkStorePathString(storePath, v);
|
mkStorePathString(storePath, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static bool isJustSchemePrefix(std::string_view prefix)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
!prefix.empty()
|
||||||
|
&& prefix[prefix.size() - 1] == ':'
|
||||||
|
&& isValidSchemeName(prefix.substr(0, prefix.size() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
bool isAllowedURI(std::string_view uri, const Strings & allowedUris)
|
bool isAllowedURI(std::string_view uri, const Strings & allowedUris)
|
||||||
{
|
{
|
||||||
/* 'uri' should be equal to a prefix, or in a subdirectory of a
|
/* 'uri' should be equal to a prefix, or in a subdirectory of a
|
||||||
|
@ -611,8 +620,14 @@ bool isAllowedURI(std::string_view uri, const Strings & allowedUris)
|
||||||
&& prefix.size() > 0
|
&& prefix.size() > 0
|
||||||
&& hasPrefix(uri, prefix)
|
&& hasPrefix(uri, prefix)
|
||||||
&& (
|
&& (
|
||||||
|
// Allow access to subdirectories of the prefix.
|
||||||
prefix[prefix.size() - 1] == '/'
|
prefix[prefix.size() - 1] == '/'
|
||||||
|| uri[prefix.size()] == '/')))
|
|| uri[prefix.size()] == '/'
|
||||||
|
|
||||||
|
// Allow access to whole schemes
|
||||||
|
|| isJustSchemePrefix(prefix)
|
||||||
|
)
|
||||||
|
))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,4 +103,39 @@ TEST(nix_isAllowedURI, file_url) {
|
||||||
ASSERT_FALSE(isAllowedURI("file://", allowed));
|
ASSERT_FALSE(isAllowedURI("file://", allowed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(nix_isAllowedURI, github_all) {
|
||||||
|
Strings allowed;
|
||||||
|
allowed.push_back("github:");
|
||||||
|
ASSERT_TRUE(isAllowedURI("github:", allowed));
|
||||||
|
ASSERT_TRUE(isAllowedURI("github:foo/bar", allowed));
|
||||||
|
ASSERT_TRUE(isAllowedURI("github:foo/bar/feat-multi-bar", allowed));
|
||||||
|
ASSERT_TRUE(isAllowedURI("github:foo/bar?ref=refs/heads/feat-multi-bar", allowed));
|
||||||
|
ASSERT_TRUE(isAllowedURI("github://foo/bar", allowed));
|
||||||
|
ASSERT_FALSE(isAllowedURI("https://github:443/foo/bar/archive/master.tar.gz", allowed));
|
||||||
|
ASSERT_FALSE(isAllowedURI("file://github:foo/bar/archive/master.tar.gz", allowed));
|
||||||
|
ASSERT_FALSE(isAllowedURI("file:///github:foo/bar/archive/master.tar.gz", allowed));
|
||||||
|
ASSERT_FALSE(isAllowedURI("github", allowed));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(nix_isAllowedURI, github_org) {
|
||||||
|
Strings allowed;
|
||||||
|
allowed.push_back("github:foo");
|
||||||
|
ASSERT_FALSE(isAllowedURI("github:", allowed));
|
||||||
|
ASSERT_TRUE(isAllowedURI("github:foo/bar", allowed));
|
||||||
|
ASSERT_TRUE(isAllowedURI("github:foo/bar/feat-multi-bar", allowed));
|
||||||
|
ASSERT_TRUE(isAllowedURI("github:foo/bar?ref=refs/heads/feat-multi-bar", allowed));
|
||||||
|
ASSERT_FALSE(isAllowedURI("github://foo/bar", allowed));
|
||||||
|
ASSERT_FALSE(isAllowedURI("https://github:443/foo/bar/archive/master.tar.gz", allowed));
|
||||||
|
ASSERT_FALSE(isAllowedURI("file://github:foo/bar/archive/master.tar.gz", allowed));
|
||||||
|
ASSERT_FALSE(isAllowedURI("file:///github:foo/bar/archive/master.tar.gz", allowed));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(nix_isAllowedURI, non_scheme_colon) {
|
||||||
|
Strings allowed;
|
||||||
|
allowed.push_back("https://foo/bar:");
|
||||||
|
ASSERT_TRUE(isAllowedURI("https://foo/bar:", allowed));
|
||||||
|
ASSERT_TRUE(isAllowedURI("https://foo/bar:/baz", allowed));
|
||||||
|
ASSERT_FALSE(isAllowedURI("https://foo/bar:baz", allowed));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
Loading…
Reference in a new issue