我有一个Poco服务器应用程序项目。该服务器应用程序用作Web服务器。现在,我想对它进行加固,使其免受目录遍历攻击,并且我正在寻找确保服务器提供的文件来自import { Component, ViewChild, HostListener } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import {MatSidenav} from '@angular/material/sidenav';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
screenWidth: number;
private screenWidth$ = new BehaviorSubject<number>(window.innerWidth);
@ViewChild('sidenav') sidenav: MatSidenav;
@HostListener('window:resize', ['$event'])
onResize(event) {
this.screenWidth$.next(event.target.innerWidth);
}
constructor() { }
ngOnInit() {
this.screenWidth$.subscribe(width => {
this.screenWidth = width;
});
}
}
内部的最佳方法。结构是
wwwRoot
例如当我将project
|-src
| |-main.cpp
|-CMakeLists.txt
|-conanfile.txt
|-build
|-...
用作build
时,wwwRoot
在conanfile.txt
之外,但是使用wwwRoot
可以打开它。我知道我可以在路径中搜索点段,但是我听说它并不是很安全,因为存在诸如编码路径之类的黑客攻击。由于我认为Poco是服务器应用程序的框架,因此已经有了这样的功能来检查localhost:8080/../conanfile.txt
是否在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
中构建了项目
答案 0 :(得分:1)
您将必须解码请求路径并逐步构建本地路径,并检查“ ..”路径段。这是执行此操作的代码段,还处理了在提供文件时应注意的其他事项。您需要编写mapContentType()
方法,或执行等效操作。
Poco::URI uri(request.getURI());
std::string decodedPath = uri.getPath();
Poco::Path requestPath(decodedPath, Poco::Path::PATH_UNIX);
Poco::Path localPath(wwwRoot.absolute());
localPath.makeDirectory();
bool valid = true;
for (int i = 0; valid && i < requestPath.depth(); i++)
{
if (requestPath[i] != "..")
localPath.pushDirectory(requestPath[i]);
else
valid = false;
}
if (valid)
{
localPath.setFileName(requestPath.getFileName());
Poco::File requestedFile(localPath.toString());
if (requestedFile.exists())
{
std::string contentType = mapContentType(localPath.getExtension());
if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_HEAD)
{
response.set("Last-Modified", Poco::DateTimeFormatter::format(dateTime, Poco::DateTimeFormat::HTTP_FORMAT));
response.setContentLength64(requestedFile.getSize());
response.setContentType(contentType);
response.send();
}
else if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET)
{
response.sendFile(localPath.toString(), contentType);
}
else
{
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_METHOD_NOT_ALLOWED);
response.send();
}
}
else
{
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_NOT_FOUND);
response.send();
}
}
else
{
response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_NOT_FOUND);
response.send();
}