mirror of
https://github.com/falcosecurity/falco.git
synced 2026-04-12 15:03:48 +00:00
Compare commits
2 Commits
master
...
fix/plugin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de93866101 | ||
|
|
f57b0e74f6 |
@@ -1,6 +1,6 @@
|
|||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
# Copyright (C) 2023 The Falco Authors.
|
# Copyright (C) 2026 The Falco Authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||||
# in compliance with the License. You may obtain a copy of the License at
|
# in compliance with the License. You may obtain a copy of the License at
|
||||||
@@ -134,10 +134,17 @@ if(NOT DEFINED FALCO_COMPONENT_NAME)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||||
set(CMAKE_INSTALL_PREFIX
|
if(WIN32)
|
||||||
/usr
|
set(CMAKE_INSTALL_PREFIX
|
||||||
CACHE PATH "Default install path" FORCE
|
"C:/Program Files/${CMAKE_PROJECT_NAME}"
|
||||||
)
|
CACHE PATH "Default install path" FORCE
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(CMAKE_INSTALL_PREFIX
|
||||||
|
/usr
|
||||||
|
CACHE PATH "Default install path" FORCE
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMD_MAKE make)
|
set(CMD_MAKE make)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2023 The Falco Authors.
|
Copyright (C) 2026 The Falco Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -146,6 +146,57 @@ plugins:
|
|||||||
EXPECT_EQ(falco_config.m_plugins[0].m_init_config, "");
|
EXPECT_EQ(falco_config.m_plugins[0].m_init_config, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Configuration, plugin_library_path_traversal) {
|
||||||
|
falco_configuration falco_config;
|
||||||
|
config_loaded_res res;
|
||||||
|
|
||||||
|
// A relative path that stays within the plugins dir should succeed.
|
||||||
|
std::string config = R"(
|
||||||
|
plugins:
|
||||||
|
- name: myplugin
|
||||||
|
library_path: libmyplugin.so
|
||||||
|
)";
|
||||||
|
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
|
||||||
|
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
|
||||||
|
|
||||||
|
// A relative path with ".." that escapes the plugins dir must be rejected.
|
||||||
|
config = R"(
|
||||||
|
plugins:
|
||||||
|
- name: evil
|
||||||
|
library_path: ../../tmp/evil.so
|
||||||
|
)";
|
||||||
|
EXPECT_THROW(falco_config.init_from_content(config, {}), std::exception);
|
||||||
|
|
||||||
|
// Traversal via "./" prefix followed by ".." must also be rejected.
|
||||||
|
config = R"(
|
||||||
|
plugins:
|
||||||
|
- name: evil
|
||||||
|
library_path: ./../../tmp/evil.so
|
||||||
|
)";
|
||||||
|
EXPECT_THROW(falco_config.init_from_content(config, {}), std::exception);
|
||||||
|
|
||||||
|
// Nested traversal that descends then escapes must be rejected.
|
||||||
|
config = R"(
|
||||||
|
plugins:
|
||||||
|
- name: evil
|
||||||
|
library_path: subdir/../../../tmp/evil.so
|
||||||
|
)";
|
||||||
|
EXPECT_THROW(falco_config.init_from_content(config, {}), std::exception);
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
// Absolute paths bypass the prefix logic and are allowed as-is.
|
||||||
|
// This test uses a Unix absolute path syntax.
|
||||||
|
config = R"(
|
||||||
|
plugins:
|
||||||
|
- name: myplugin
|
||||||
|
library_path: /opt/falco/plugins/libmyplugin.so
|
||||||
|
)";
|
||||||
|
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
|
||||||
|
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
|
||||||
|
EXPECT_EQ(falco_config.m_plugins[0].m_library_path, "/opt/falco/plugins/libmyplugin.so");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Configuration, schema_yaml_helper_validator) {
|
TEST(Configuration, schema_yaml_helper_validator) {
|
||||||
yaml_helper conf;
|
yaml_helper conf;
|
||||||
falco_configuration falco_config;
|
falco_configuration falco_config;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2025 The Falco Authors.
|
Copyright (C) 2026 The Falco Authors.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -31,6 +31,7 @@ limitations under the License.
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include "config_falco.h"
|
#include "config_falco.h"
|
||||||
#include "yaml_helper.h"
|
#include "yaml_helper.h"
|
||||||
@@ -400,9 +401,35 @@ struct convert<falco_configuration::plugin_config> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rhs.m_library_path = node["library_path"].as<std::string>();
|
rhs.m_library_path = node["library_path"].as<std::string>();
|
||||||
if(!rhs.m_library_path.empty() && rhs.m_library_path.at(0) != '/') {
|
if(!rhs.m_library_path.empty() &&
|
||||||
// prepend share dir if path is not absolute
|
!std::filesystem::path(rhs.m_library_path).is_absolute() &&
|
||||||
rhs.m_library_path = std::string(FALCO_ENGINE_PLUGINS_DIR) + rhs.m_library_path;
|
rhs.m_library_path.at(0) != '/') {
|
||||||
|
// Relative path: resolve against the plugins directory
|
||||||
|
// and verify the result stays within it.
|
||||||
|
auto full_path = std::filesystem::path(FALCO_ENGINE_PLUGINS_DIR) / rhs.m_library_path;
|
||||||
|
// lexically_normal resolves . and .. purely lexically,
|
||||||
|
// without filesystem access (unlike weakly_canonical which
|
||||||
|
// leaves .. unresolved for non-existent path components).
|
||||||
|
auto normalized = full_path.lexically_normal();
|
||||||
|
auto plugins_dir = std::filesystem::path(FALCO_ENGINE_PLUGINS_DIR).lexically_normal();
|
||||||
|
auto rel = normalized.lexically_relative(plugins_dir);
|
||||||
|
if(rel.empty()) {
|
||||||
|
throw YAML::Exception(node["library_path"].Mark(),
|
||||||
|
"plugin library_path '" +
|
||||||
|
node["library_path"].as<std::string>() +
|
||||||
|
"' resolves outside the plugins directory (" +
|
||||||
|
std::string(FALCO_ENGINE_PLUGINS_DIR) + ")");
|
||||||
|
}
|
||||||
|
for(const auto& component : rel) {
|
||||||
|
if(component == "..") {
|
||||||
|
throw YAML::Exception(node["library_path"].Mark(),
|
||||||
|
"plugin library_path '" +
|
||||||
|
node["library_path"].as<std::string>() +
|
||||||
|
"' resolves outside the plugins directory (" +
|
||||||
|
std::string(FALCO_ENGINE_PLUGINS_DIR) + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rhs.m_library_path = normalized.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node["init_config"] && !node["init_config"].IsNull()) {
|
if(node["init_config"] && !node["init_config"].IsNull()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user