From 6d8aa453ab920b374b6a46b954fd6e2d7f5a44c8 Mon Sep 17 00:00:00 2001 From: Jan Holesovsky Date: Wed, 10 May 2017 14:46:21 +0200 Subject: [PATCH] wsd: Handle a non-empty, but broken frame ancestor with 'deny' too. Change-Id: I61b6e5c7cbe7f36ecd780865a613b7a240cf7b99 --- wsd/FileServer.cpp | 56 ++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index 7d7dba3ef..c61df9fa7 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -394,32 +394,6 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: { const auto host = ((LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination()) ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName); const auto params = Poco::URI(request.getURI()).getQueryParameters(); - std::string frameAncestor; - const auto it = request.find("Referer"); // Referer[sic] - if (it != request.end()) - { - frameAncestor = it->second; - LOG_TRC("Picking frame ancestor from HTTP Referer header: " << frameAncestor); - } - else // Use WOPISrc value if Referer is absent - { - for (const auto& param : params) - { - if (param.first == "WOPISrc") - { - Poco::URI::decode(param.second, frameAncestor); - LOG_TRC("Picking frame ancestor from WOPISrc: " << frameAncestor); - break; - } - } - } - - // Keep only the origin, reject everything else - if (!Poco::URI(frameAncestor).getScheme().empty() && !Poco::URI(frameAncestor).getHost().empty()) - { - frameAncestor = Poco::URI(frameAncestor).getScheme() + "://" + Poco::URI(frameAncestor).getHost(); - LOG_TRC("Final frame ancestor: " << frameAncestor); - } // Is this a file we read at startup - if not; its not for serving. const std::string relPath = getRequestPathname(request); @@ -504,14 +478,42 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: << "style-src 'self' 'unsafe-inline'; " << "font-src 'self' data:; " << "img-src 'self' data:; "; - if (!frameAncestor.empty()) + + std::string frameAncestor; + const auto it = request.find("Referer"); // Referer[sic] + if (it != request.end()) { + frameAncestor = it->second; + LOG_TRC("Picking frame ancestor from HTTP Referer header: " << frameAncestor); + } + else // Use WOPISrc value if Referer is absent + { + for (const auto& param : params) + { + if (param.first == "WOPISrc") + { + Poco::URI::decode(param.second, frameAncestor); + LOG_TRC("Picking frame ancestor from WOPISrc: " << frameAncestor); + break; + } + } + } + + // Keep only the origin, reject everything else + Poco::URI uriFrameAncestor(frameAncestor); + if (!frameAncestor.empty() && !uriFrameAncestor.getScheme().empty() && !uriFrameAncestor.getHost().empty()) + { + frameAncestor = uriFrameAncestor.getScheme() + "://" + uriFrameAncestor.getHost(); + LOG_TRC("Final frame ancestor: " << frameAncestor); + // Replaced by frame-ancestors in CSP but some oldies don't know about that oss << "X-Frame-Options: allow-from " << frameAncestor << "\r\n"; cspOss << "frame-ancestors " << frameAncestor; } else { + LOG_TRC("Denied frame ancestor: " << frameAncestor); + oss << "X-Frame-Options: deny\r\n"; }