aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorauzhegov <auzhegov@yandex-team.com>2023-08-23 14:58:36 +0300
committerauzhegov <auzhegov@yandex-team.com>2023-08-23 15:32:25 +0300
commit5ba6ac44dabe4ac45b7fe1430ec4eeeb35ce2124 (patch)
treeacc0666d995cbeb91a4d4cbb7592235caf490694
parent6e7d3a73ff044dd6bff7936fa9b8ec956e0568c7 (diff)
downloadydb-5ba6ac44dabe4ac45b7fe1430ec4eeeb35ce2124.tar.gz
Allowlist validation
-rw-r--r--ydb/core/fq/libs/control_plane_storage/request_validators.cpp45
-rw-r--r--ydb/core/fq/libs/control_plane_storage/request_validators.h12
2 files changed, 50 insertions, 7 deletions
diff --git a/ydb/core/fq/libs/control_plane_storage/request_validators.cpp b/ydb/core/fq/libs/control_plane_storage/request_validators.cpp
index ca21f6f086..eea91a2b5c 100644
--- a/ydb/core/fq/libs/control_plane_storage/request_validators.cpp
+++ b/ydb/core/fq/libs/control_plane_storage/request_validators.cpp
@@ -370,4 +370,49 @@ NYql::TIssues ValidateProjection(const FederatedQuery::Schema& schema, const TSt
return issues;
}
+NYql::TIssues ValidateEntityName(const TString& name) {
+ NYql::TIssues issues;
+
+ if (!name) {
+ issues.AddIssue(
+ MakeErrorIssue(TIssuesIds::BAD_REQUEST, "name field is not specified"));
+ }
+
+ if (name.Size() > 255) {
+ issues.AddIssue(
+ MakeErrorIssue(TIssuesIds::BAD_REQUEST,
+ TStringBuilder{}
+ << "Incorrect connection name: " << name
+ << ". Name length must not exceed 255 symbols. Current length is "
+ << name.Size() << " symbol(s)"));
+ }
+
+ if (name != to_lower(name)) {
+ issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST,
+ TStringBuilder{}
+ << "Incorrect binding name: " << name
+ << ". Please use only lower case"));
+ }
+
+ if (AllOf(name, [](auto& ch) { return ch == '.'; })) {
+ issues.AddIssue(
+ MakeErrorIssue(TIssuesIds::BAD_REQUEST,
+ TStringBuilder{}
+ << "Incorrect connection name: " << name
+ << ". Name is not allowed path part contains only dots"));
+ }
+
+ static const std::regex allowListRegexp(
+ "(?:[a-z0-9]|!|\\\\|#|\\$|%|&|\\(|\\)|\\*|\\+|,|-|\\.|:|;|<|=|>|\\?|@|\\[|\\]|\\^|_|\\{|\\||\\}|~)+");
+ if (!std::regex_match(name.c_str(), allowListRegexp)) {
+ issues.AddIssue(MakeErrorIssue(
+ TIssuesIds::BAD_REQUEST,
+ TStringBuilder{}
+ << "Incorrect connection name: " << name
+ << ". Please make sure that name consists of following symbols: ['a'-'z'], ['0'-'9'], '!', '\\', '#', '$', '%'. '&', '(', ')', '*', '+', ',', '-', '.', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '{', '|', '}', '~'"));
+ }
+
+ return issues;
+}
+
} // namespace NFq
diff --git a/ydb/core/fq/libs/control_plane_storage/request_validators.h b/ydb/core/fq/libs/control_plane_storage/request_validators.h
index c770cb1454..add489ae06 100644
--- a/ydb/core/fq/libs/control_plane_storage/request_validators.h
+++ b/ydb/core/fq/libs/control_plane_storage/request_validators.h
@@ -7,12 +7,13 @@
#include <ydb/library/yql/public/issue/yql_issue.h>
#include <ydb/public/api/protos/draft/fq.pb.h>
+#include <library/cpp/scheme/scheme.h>
#include <util/generic/fwd.h>
#include <util/generic/set.h>
#include <util/string/builder.h>
#include <util/string/cast.h>
-#include <library/cpp/scheme/scheme.h>
+#include <regex>
namespace NFq {
@@ -82,6 +83,7 @@ NYql::TIssues ValidateFormatSetting(const TString& format, const google::protobu
NYql::TIssues ValidateDateFormatSetting(const google::protobuf::Map<TString, TString>& formatSetting, bool matchAllSettings = false);
NYql::TIssues ValidateProjectionColumns(const FederatedQuery::Schema& schema, const TVector<TString>& partitionedBy);
NYql::TIssues ValidateProjection(const FederatedQuery::Schema& schema, const TString& projection, const TVector<TString>& partitionedBy, size_t pathsLimit);
+NYql::TIssues ValidateEntityName(const TString& name);
template<typename T>
NYql::TIssues ValidateBinding(const T& ev, size_t maxSize, const TSet<FederatedQuery::BindingSetting::BindingCase>& availableBindings, size_t pathsLimit)
@@ -95,9 +97,7 @@ NYql::TIssues ValidateBinding(const T& ev, size_t maxSize, const TSet<FederatedQ
issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, "binding.acl.visibility field is not specified"));
}
- if (content.name() != to_lower(content.name())) {
- issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, TStringBuilder{} << "Incorrect binding name: " << content.name() << ". Please use only lower case"));
- }
+ issues.AddIssues(ValidateEntityName(content.name()));
if (!content.has_setting()) {
issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, "binding.setting field is not specified"));
@@ -179,9 +179,7 @@ NYql::TIssues ValidateConnection(
issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, "content.acl.visibility field is not specified"));
}
- if (content.name() != to_lower(content.name())) {
- issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, TStringBuilder{} << "Incorrect connection name: " << content.name() << ". Please use only lower case"));
- }
+ issues.AddIssues(ValidateEntityName(content.name()));
if (!content.has_setting()) {
issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, "content.setting field is not specified"));