From cd6c5976ccfe817b2e0a2d46227cd361bfefb45c Mon Sep 17 00:00:00 2001
From: dutor <440396+dutor@users.noreply.github.com>
Date: Wed, 28 Aug 2024 14:57:47 +0800
Subject: [PATCH] Fixed vulnerability issues

---
 src/common/network/NetworkUtils.cpp           | 12 ++++++++++
 src/common/network/NetworkUtils.h             |  2 ++
 .../processors/job/DownloadJobExecutor.cpp    | 23 ++++++++++++++-----
 src/webservice/SetFlagsHandler.cpp            |  8 +++++++
 4 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/src/common/network/NetworkUtils.cpp b/src/common/network/NetworkUtils.cpp
index 43d67d892be..1e302a9dc90 100644
--- a/src/common/network/NetworkUtils.cpp
+++ b/src/common/network/NetworkUtils.cpp
@@ -307,6 +307,18 @@ std::string NetworkUtils::toHostsStr(const std::vector<HostAddr>& hosts) {
   return hostsString;
 }
 
+Status NetworkUtils::validateIP(const std::string& ip) {
+  if (ip.empty()) {
+    return Status::Error("ip is empty.");
+  }
+  static const std::regex ipv4(
+      R"(^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$)");
+  if (!std::regex_match(ip, ipv4)) {
+    return Status::Error("%s is not a valid IP", ip.c_str());
+  }
+  return Status::OK();
+}
+
 Status NetworkUtils::validateHostOrIp(const std::string& hostOrIp) {
   if (hostOrIp.empty()) {
     return Status::Error("local_ip is empty, need to config it through config file.");
diff --git a/src/common/network/NetworkUtils.h b/src/common/network/NetworkUtils.h
index f5cd7921113..30528e0edfd 100644
--- a/src/common/network/NetworkUtils.h
+++ b/src/common/network/NetworkUtils.h
@@ -50,6 +50,8 @@ class NetworkUtils final {
   static StatusOr<std::vector<HostAddr>> toHosts(const std::string& peersStr);
   static std::string toHostsStr(const std::vector<HostAddr>& hosts);
 
+  static Status validateIP(const std::string& ip);
+
   static Status validateHostOrIp(const std::string& HostOrIp);
 
  private:
diff --git a/src/meta/processors/job/DownloadJobExecutor.cpp b/src/meta/processors/job/DownloadJobExecutor.cpp
index 996c75c5f23..65ee49e734d 100644
--- a/src/meta/processors/job/DownloadJobExecutor.cpp
+++ b/src/meta/processors/job/DownloadJobExecutor.cpp
@@ -8,6 +8,7 @@
 #include "common/hdfs/HdfsHelper.h"
 #include "common/utils/MetaKeyUtils.h"
 #include "meta/MetaServiceUtils.h"
+#include "meta/processors/BaseProcessor.h"
 
 namespace nebula {
 namespace meta {
@@ -34,20 +35,30 @@ nebula::cpp2::ErrorCode DownloadJobExecutor::check() {
   }
 
   auto u = url.substr(hdfsPrefix.size(), url.size());
-  std::vector<folly::StringPiece> tokens;
+  std::vector<std::string> tokens;
   folly::split(":", u, tokens);
   if (tokens.size() == 2) {
+    if (!NetworkUtils::validateIP(tokens[0]).ok()) {
+      LOG(ERROR) << "Illegal hdfs host: " << url;
+      return nebula::cpp2::ErrorCode::E_INVALID_JOB;
+    }
     host_ = std::make_unique<std::string>(tokens[0]);
-    int32_t position = tokens[1].find_first_of("/");
-    if (position != -1) {
+    auto position = tokens[1].find_first_of("/");
+    if (position != std::string::npos) {
       try {
-        port_ = folly::to<int32_t>(tokens[1].toString().substr(0, position).c_str());
+        port_ = folly::to<int32_t>(tokens[1].substr(0, position).c_str());
       } catch (const std::exception& ex) {
         LOG(ERROR) << "URL's port parse failed: " << url;
         return nebula::cpp2::ErrorCode::E_INVALID_JOB;
       }
-      path_ =
-          std::make_unique<std::string>(tokens[1].toString().substr(position, tokens[1].size()));
+      auto path = tokens[1].substr(position, tokens[1].size());
+      // A valid hdfs path must start with /, and only regular characters allow for now
+      const std::regex pattern("^/[-_/0-9a-zA-Z]*$");
+      if (!std::regex_match(path, pattern)) {
+        LOG(ERROR) << "Illegal hdfs path: " << url;
+        return nebula::cpp2::ErrorCode::E_INVALID_JOB;
+      }
+      path_ = std::make_unique<std::string>(path);
     } else {
       LOG(ERROR) << "URL Parse Failed: " << url;
       return nebula::cpp2::ErrorCode::E_INVALID_JOB;
diff --git a/src/webservice/SetFlagsHandler.cpp b/src/webservice/SetFlagsHandler.cpp
index 6a8de177279..660a5c04d1c 100644
--- a/src/webservice/SetFlagsHandler.cpp
+++ b/src/webservice/SetFlagsHandler.cpp
@@ -79,6 +79,14 @@ void SetFlagsHandler::onEOM() noexcept {
   for (auto &item : flags.items()) {
     try {
       const std::string &name = item.first.asString();
+      if (name == "enable_authorize") {
+        LOG(ERROR) << "Modifying enable_authorize is not allowed";
+        ResponseBuilder(downstream_)
+            .status(WebServiceUtils::to(HttpStatusCode::BAD_REQUEST),
+                    WebServiceUtils::toString(HttpStatusCode::BAD_REQUEST))
+            .sendWithEOM();
+        return;
+      }
       const std::string &value = item.second.asString();
       const std::string &newValue = gflags::SetCommandLineOption(name.c_str(), value.c_str());
       if (newValue.empty()) {