У меня есть проект приложения сервера Poco.Это серверное приложение работает как веб-сервер.Теперь я хочу защитить его от атак через каталоги и ищу лучший способ защитить файлы, которые обслуживает сервер, изнутри wwwRoot
.Структура
project
|-src
| |-main.cpp
|-CMakeLists.txt
|-conanfile.txt
|-build
|-...
Например, когда я использую build
, поскольку wwwRoot
, conanfile.txt
находится за пределами wwwRoot
, но с помощью localhost:8080/../conanfile.txt
я могу открыть его.Я знаю, что могу искать путь по точечным сегментам, но я слышал, что это не совсем безопасно, поскольку существуют такие хаки, как закодированные пути.Поскольку Poco - это фреймворк для серверных приложений, я предполагаю, что уже есть такая функция для проверки того, находится ли filePath
внутри wwwRoot
, но я не могу ее найти.
src/main.cpp
содержит:
#include <Poco/Net/HTTPServer.h>
#include <Poco/Net/ServerSocket.h>
#include <Poco/Util/ServerApplication.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/Path.h>
#include <string>
class FileHandler: public Poco::Net::HTTPRequestHandler {
public:
explicit FileHandler(const Poco::Path &wwwRoot);
protected:
void handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) override;
private:
Poco::Path wwwRoot;
};
FileHandler::FileHandler(const Poco::Path &aWwwRoot) : wwwRoot(aWwwRoot) {}
void FileHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) {
Poco::Util::Application &app = Poco::Util::Application::instance();
app.logger().information("FileHandler Request from " + request.clientAddress().toString() + ": " + request.getURI());
Poco::Path path(wwwRoot.absolute(), request.getURI());
std::string filePath(path.toString());
app.logger().information(filePath);
response.sendFile(filePath, "text/html");
}
class HTTPRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory {
public:
explicit HTTPRequestHandlerFactory(const Poco::Path &wwwRoot);
protected:
Poco::Net::HTTPRequestHandler* createRequestHandler(
const Poco::Net::HTTPServerRequest& request) override;
private:
Poco::Path wwwRoot;
};
HTTPRequestHandlerFactory::HTTPRequestHandlerFactory(const Poco::Path &aWwwRoot) : wwwRoot(aWwwRoot) {}
Poco::Net::HTTPRequestHandler* HTTPRequestHandlerFactory::createRequestHandler(
const Poco::Net::HTTPServerRequest &) {
return new FileHandler(wwwRoot);
}
class ServerApplication : public Poco::Util::ServerApplication {
protected:
void initialize(Application& self) override;
int main(const std::vector<std::string> &args) override;
};
void ServerApplication::initialize(Application& self) {
loadConfiguration();
Poco::Util::ServerApplication::initialize(self);
}
int ServerApplication::main(const std::vector<std::string> &) {
Poco::Net::ServerSocket svs(8080);
Poco::Net::HTTPServer srv(new HTTPRequestHandlerFactory(Poco::Path(".").absolute()),
svs, new Poco::Net::HTTPServerParams);
srv.start();
waitForTerminationRequest();
srv.stop();
return Application::EXIT_OK;
}
int main(int argc, char **argv) {
ServerApplication app;
return app.run(argc, argv);
}
CMakeLists.txt
содержит:
cmake_minimum_required (VERSION 3.5.1)
project (Sandbox)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_CXX_STANDARD 14)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE CONAN_PKG::Poco)
conanfile.txt
содержит:
[requires]
Poco/1.9.0@pocoproject/stable
[generators]
cmake
В build
проект построен