docs: Add 1 and update 6 files
This commit is contained in:
@@ -199,6 +199,7 @@ void Server::setup_routes() {
|
||||
void Server::handle_cors_preflight(const drogon::HttpRequestPtr& req, std::function<void(const drogon::HttpResponsePtr &)>&& callback) {
|
||||
auto resp = drogon::HttpResponse::newHttpResponse();
|
||||
add_cors_headers(req, resp);
|
||||
add_security_headers(resp);
|
||||
resp->setStatusCode(drogon::k204NoContent);
|
||||
callback(resp);
|
||||
}
|
||||
@@ -240,6 +241,33 @@ void Server::add_cors_headers(const drogon::HttpRequestPtr& req, const drogon::H
|
||||
}
|
||||
}
|
||||
|
||||
void Server::add_security_headers(const drogon::HttpResponsePtr& res) {
|
||||
// Add security headers to prevent common web vulnerabilities
|
||||
|
||||
// Prevent clickjacking attacks
|
||||
res->addHeader("X-Frame-Options", "DENY");
|
||||
|
||||
// Prevent MIME type sniffing
|
||||
res->addHeader("X-Content-Type-Options", "nosniff");
|
||||
|
||||
// Enable XSS filter in browsers (legacy, but still useful for older browsers)
|
||||
res->addHeader("X-XSS-Protection", "1; mode=block");
|
||||
|
||||
// Enforce HTTPS (only add if we're sure the server uses HTTPS)
|
||||
// Note: Commented out by default as it requires HTTPS to be configured
|
||||
// res->addHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
|
||||
|
||||
// Content Security Policy - restrictive by default
|
||||
// This prevents loading of external resources and inline scripts
|
||||
res->addHeader("Content-Security-Policy", "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'");
|
||||
|
||||
// Referrer Policy - don't leak referrer information
|
||||
res->addHeader("Referrer-Policy", "strict-origin-when-cross-origin");
|
||||
|
||||
// Permissions Policy (formerly Feature Policy) - disable unnecessary browser features
|
||||
res->addHeader("Permissions-Policy", "geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()");
|
||||
}
|
||||
|
||||
std::string Server::join(const std::vector<std::string>& strings, const std::string& delimiter) {
|
||||
if (strings.empty()) return "";
|
||||
|
||||
@@ -261,6 +289,7 @@ void Server::handle_get_object(const drogon::HttpRequestPtr& req, std::function<
|
||||
nlohmann::json response = {{"result", "error"}, {"error", "Couldn't find: " + key}};
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
@@ -273,12 +302,14 @@ void Server::handle_get_object(const drogon::HttpRequestPtr& req, std::function<
|
||||
nlohmann::json response = {{"result", "error"}, {"error", "Hash recognised, but object missing for: " + entry.hash}};
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send file
|
||||
auto resp = drogon::HttpResponse::newFileResponse(file_path.string());
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
@@ -292,6 +323,7 @@ void Server::handle_get_hash(const drogon::HttpRequestPtr& req, std::function<vo
|
||||
nlohmann::json response = {{"result", "error"}, {"error", "Label:tag not found"}};
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
@@ -300,6 +332,7 @@ void Server::handle_get_hash(const drogon::HttpRequestPtr& req, std::function<vo
|
||||
nlohmann::json response = {{"result", "success"}, {"hash", entry.hash}};
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
@@ -312,6 +345,7 @@ void Server::handle_get_directory(const drogon::HttpRequestPtr& /*req*/, std::fu
|
||||
nlohmann::json response = {{"result", "error"}, {"error", "Failed to retrieve directory listing"}};
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
@@ -326,6 +360,7 @@ void Server::handle_get_directory(const drogon::HttpRequestPtr& /*req*/, std::fu
|
||||
nlohmann::json response = {{"result", "success"}, {"entries", entries_array}};
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
@@ -356,6 +391,7 @@ void Server::handle_get_metadata(const drogon::HttpRequestPtr& req, std::functio
|
||||
resp->setBody(response.dump());
|
||||
}
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
@@ -374,6 +410,7 @@ void Server::handle_delete_object(const drogon::HttpRequestPtr& req, std::functi
|
||||
{
|
||||
std::map<std::string, std::string> params;
|
||||
if (!validate_write_request(req, resp, {"hash"}, params)) {
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
@@ -394,6 +431,7 @@ void Server::handle_delete_object(const drogon::HttpRequestPtr& req, std::functi
|
||||
nlohmann::json response = {{"result", "error"}, {"error", "Failed to remove some or all associated tags"}};
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
@@ -417,6 +455,7 @@ void Server::handle_delete_object(const drogon::HttpRequestPtr& req, std::functi
|
||||
nlohmann::json response = {{"result", "success"}};
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
@@ -431,6 +470,7 @@ void Server::handle_exists(const drogon::HttpRequestPtr& req, std::function<void
|
||||
auto resp = drogon::HttpResponse::newHttpResponse();
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
@@ -448,6 +488,7 @@ void Server::handle_get_version(const drogon::HttpRequestPtr& req, std::function
|
||||
nlohmann::json response = {{"result", "failed"}, {"error", "Failed to get version for: " + key}};
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
@@ -460,6 +501,7 @@ void Server::handle_get_version(const drogon::HttpRequestPtr& req, std::function
|
||||
}
|
||||
resp->setBody(response.dump());
|
||||
resp->setContentTypeCode(drogon::CT_APPLICATION_JSON);
|
||||
add_security_headers(resp);
|
||||
callback(resp);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user