[Libreoffice-commits] online.git: 2 commits - wsd/FileServer.cpp wsd/FileServer.hpp
Pranav Kant
pranavk at collabora.co.uk
Mon Apr 10 09:56:35 UTC 2017
wsd/FileServer.cpp | 71 +++++++++++++++++++++++++++++++----------------------
wsd/FileServer.hpp | 8 ++---
2 files changed, 45 insertions(+), 34 deletions(-)
New commits:
commit 74020e0f1ffa0a6a2448135440c7ba03482f0bea
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Mon Apr 10 15:04:51 2017 +0530
Revert "wsd: Fileserver cleanup"
This reverts commit de2bc17c04af088d9c7e18a97216b174494e1a9c.
Lets not introduce any cleanup commits while we are near a release, will
apply it again after the release. The cleanup is supposed to not handle
the custom file server root correctly, so don't forget to test it with
a custom file server root before re-reverting.
It changes the path where loleaflet.html is searched for from
/usr/share/loolwsd/loleaflet/... to /usr/share/loleaflet/...
and doesn't find it there.
Change-Id: I23940e9a3e06721f0a8b7493a526f42d2072cfa4
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index 6c892f3d..9f056903 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -44,8 +44,8 @@ using Poco::Net::HTTPBasicCredentials;
using Poco::StreamCopier;
using Poco::Util::Application;
-bool FileServerRequestHandler::tryAdminLogin(const HTTPRequest& request,
- HTTPResponse &response)
+bool FileServerRequestHandler::isAdminLoggedIn(const HTTPRequest& request,
+ HTTPResponse &response)
{
const auto& config = Application::instance().config();
const auto sslKeyPath = config.getString("ssl.key_file_path", "");
@@ -109,43 +109,56 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M
{
bool noCache = false;
Poco::Net::HTTPResponse response;
- const auto requestPathname = Poco::Path(getRequestPathname(request));
- const auto filePath = Poco::Path(LOOLWSD::FileServerRoot, requestPathname);
- const auto file = Poco::File(filePath);
- LOG_TRC("Fileserver request: " << requestPathname.toString() << ", " <<
- "Resolved file path: " << filePath.toString());
-
- if (!file.exists() ||
- requestPathname[0] != "loleaflet" ||
- requestPathname[1] != "dist")
+ Poco::URI requestUri(request.getURI());
+ LOG_TRC("Fileserver request: " << requestUri.toString());
+ requestUri.normalize(); // avoid .'s and ..'s
+
+ std::vector<std::string> requestSegments;
+ requestUri.getPathSegments(requestSegments);
+ if (requestSegments.size() < 1)
{
- throw Poco::FileNotFoundException("Invalid URI request: [" + filePath.toString() + "].");
+ throw Poco::FileNotFoundException("Invalid URI request: [" + requestUri.toString() + "].");
}
const auto& config = Application::instance().config();
const std::string loleafletHtml = config.getString("loleaflet_html", "loleaflet.html");
- if (filePath.getFileName() == loleafletHtml)
+ const std::string endPoint = requestSegments[requestSegments.size() - 1];
+ if (endPoint == loleafletHtml)
{
- preprocessAndSendLoleafletHtml(request, message, socket);
+ preprocessFile(request, message, socket);
return;
}
if (request.getMethod() == HTTPRequest::HTTP_GET)
{
- if (filePath.getFileName() == "admin.html" ||
- filePath.getFileName() == "adminSettings.html" ||
- filePath.getFileName() == "adminAnalytics.html")
+ if (endPoint == "admin.html" ||
+ endPoint == "adminSettings.html" ||
+ endPoint == "adminAnalytics.html")
{
noCache = true;
- if (!FileServerRequestHandler::tryAdminLogin(request, response))
+ if (!FileServerRequestHandler::isAdminLoggedIn(request, response))
throw Poco::Net::NotAuthenticatedException("Invalid admin login");
// Ask UAs to block if they detect any XSS attempt
response.add("X-XSS-Protection", "1; mode=block");
}
- const std::string fileType = filePath.getExtension();
+ const auto path = Poco::Path(LOOLWSD::FileServerRoot, getRequestPathname(request));
+ const auto filepath = path.absolute().toString();
+ if (filepath.find(LOOLWSD::FileServerRoot) != 0)
+ {
+ // Accessing unauthorized path.
+ throw Poco::FileAccessDeniedException("Invalid or forbidden file path: [" + filepath + "].");
+ }
+
+ const std::size_t extPoint = endPoint.find_last_of('.');
+ if (extPoint == std::string::npos)
+ {
+ throw Poco::FileNotFoundException("Invalid file.");
+ }
+
+ const std::string fileType = endPoint.substr(extPoint + 1);
std::string mimeType;
if (fileType == "js")
mimeType = "application/javascript";
@@ -184,7 +197,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M
}
bool deflate = request.hasToken("Accept-Encoding", "deflate");
- HttpHelper::sendFile(socket, filePath.toString(), mimeType, response, noCache, deflate);
+ HttpHelper::sendFile(socket, filepath, mimeType, response, noCache, deflate);
}
}
catch (const Poco::Net::NotAuthenticatedException& exc)
@@ -237,17 +250,13 @@ std::string FileServerRequestHandler::getRequestPathname(const HTTPRequest& requ
std::string path(requestUri.getPath());
- // Remove first foreslash as the root ends in one.
- if (path[0] == '/')
- path = path.substr(1);
-
- // Convert version back to a real file name.
- Poco::replaceInPlace(path, std::string("loleaflet/" LOOLWSD_VERSION_HASH "/"), std::string("loleaflet/dist/"));
+ // Convert version back to a real file name. Remove first foreslash as the root ends in one.
+ Poco::replaceInPlace(path, std::string("/loleaflet/" LOOLWSD_VERSION_HASH "/"), std::string("loleaflet/dist/"));
return path;
}
-void FileServerRequestHandler::preprocessAndSendLoleafletHtml(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket)
+void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket)
{
const auto host = ((LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination()) ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName);
const auto params = Poco::URI(request.getURI()).getQueryParameters();
diff --git a/wsd/FileServer.hpp b/wsd/FileServer.hpp
index 3ba6803f..b27526f3 100644
--- a/wsd/FileServer.hpp
+++ b/wsd/FileServer.hpp
@@ -20,13 +20,11 @@ class FileServerRequestHandler
{
static std::string getRequestPathname(const Poco::Net::HTTPRequest& request);
- static void preprocessAndSendLoleafletHtml(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket);
+ static void preprocessFile(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket);
public:
- /// If valid cookies exists in request, log the admin in (returns true)
- /// If no cookie exist check the credentials, set the cookie and log the admin in
- /// In case no valid cookie exists or invalid or no credentials exist, return false
- static bool tryAdminLogin(const Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response);
+ /// Evaluate if the cookie exists, and if not, ask for the credentials.
+ static bool isAdminLoggedIn(const Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response);
static void handleRequest(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket);
};
commit a0d7c33877c266db0ef88c32645c69a6ad892216
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Sun Apr 9 23:53:45 2017 +0530
security: X-Frame-Options: Deny framing if no wopi host
Change-Id: I6936f8a11e3e076e111e0883305f47064e032983
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index 07c9857b..6c892f3d 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -340,8 +340,12 @@ void FileServerRequestHandler::preprocessAndSendLoleafletHtml(const HTTPRequest&
if (!wopiDomain.empty())
{
- oss << "X-Frame-Options: allow-from " << wopiDomain << "\r\n"
- << "Content-Security-Policy: frame-ancestors " << wopiDomain << "\r\n";
+ oss << "X-Frame-Options: allow-from " << wopiDomain << "\r\n";
+ oss << "Content-Security-Policy: frame-ancestors " << wopiDomain << "\r\n";
+ }
+ else
+ {
+ oss << "X-Frame-Options: deny\r\n";
}
oss << "\r\n"
More information about the Libreoffice-commits
mailing list