From 7fd30fa90f08efebcf79daf5a40c48cfb57bee9a Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 10 Dec 2018 22:14:53 +0800 Subject: [PATCH 1/2] Enforce referrer-policy in WebUI This stops leaking private data to other websites via Referrer header. --- src/base/http/types.h | 1 + src/webui/webapplication.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/base/http/types.h b/src/base/http/types.h index 464e53920..a38e3d328 100644 --- a/src/base/http/types.h +++ b/src/base/http/types.h @@ -52,6 +52,7 @@ namespace Http const char HEADER_HOST[] = "host"; const char HEADER_ORIGIN[] = "origin"; const char HEADER_REFERER[] = "referer"; + const char HEADER_REFERRER_POLICY[] = "referrer-policy"; const char HEADER_SET_COOKIE[] = "set-cookie"; const char HEADER_X_CONTENT_TYPE_OPTIONS[] = "x-content-type-options"; const char HEADER_X_FORWARDED_HOST[] = "x-forwarded-host"; diff --git a/src/webui/webapplication.cpp b/src/webui/webapplication.cpp index b16a466c2..dac8f155f 100644 --- a/src/webui/webapplication.cpp +++ b/src/webui/webapplication.cpp @@ -570,9 +570,11 @@ Http::Response WebApplication::processRequest(const Http::Request &request, cons if (m_isHttpsEnabled) { csp += QLatin1String(" upgrade-insecure-requests;"); } - header(Http::HEADER_CONTENT_SECURITY_POLICY, csp); + if (!m_isAltUIUsed) + header(Http::HEADER_REFERRER_POLICY, "same-origin"); + return response(); } From c1912e17c18edaba3a2feabdc5242aabdf4506d7 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 10 Dec 2018 22:26:46 +0800 Subject: [PATCH 2/2] Revise CSP header The majority of the CSP is tuned for built-in WebUI, it may not be suitable for alternative UI. Also add QLatin1String to strings. This code path is called repeatedly, it is worth adding QLatin1String to squeeze out the last bit of performance. --- src/webui/webapplication.cpp | 27 +++++++++++++++------------ src/webui/webapplication.h | 1 + 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/webui/webapplication.cpp b/src/webui/webapplication.cpp index dac8f155f..5b38e887d 100644 --- a/src/webui/webapplication.cpp +++ b/src/webui/webapplication.cpp @@ -457,6 +457,13 @@ void WebApplication::configure() m_isCSRFProtectionEnabled = pref->isWebUiCSRFProtectionEnabled(); m_isHostHeaderValidationEnabled = pref->isWebUIHostHeaderValidationEnabled(); m_isHttpsEnabled = pref->isWebUiHttpsEnabled(); + + m_contentSecurityPolicy = + (m_isAltUIUsed + ? QLatin1String("") + : QLatin1String("default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; object-src 'none'; form-action 'self';")) + + (m_isClickjackingProtectionEnabled ? QLatin1String(" frame-ancestors 'self';") : QLatin1String("")) + + (m_isHttpsEnabled ? QLatin1String(" upgrade-insecure-requests;") : QLatin1String("")); } void WebApplication::registerAPIController(const QString &scope, APIController *controller) @@ -559,21 +566,17 @@ Http::Response WebApplication::processRequest(const Http::Request &request, cons print(error.message(), Http::CONTENT_TYPE_TXT); } - header(Http::HEADER_X_XSS_PROTECTION, "1; mode=block"); - header(Http::HEADER_X_CONTENT_TYPE_OPTIONS, "nosniff"); + header(QLatin1String(Http::HEADER_X_XSS_PROTECTION), QLatin1String("1; mode=block")); + header(QLatin1String(Http::HEADER_X_CONTENT_TYPE_OPTIONS), QLatin1String("nosniff")); - QString csp = QLatin1String("default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; object-src 'none'; form-action 'self';"); - if (m_isClickjackingProtectionEnabled) { - header(Http::HEADER_X_FRAME_OPTIONS, "SAMEORIGIN"); - csp += QLatin1String(" frame-ancestors 'self';"); - } - if (m_isHttpsEnabled) { - csp += QLatin1String(" upgrade-insecure-requests;"); - } - header(Http::HEADER_CONTENT_SECURITY_POLICY, csp); + if (m_isClickjackingProtectionEnabled) + header(QLatin1String(Http::HEADER_X_FRAME_OPTIONS), QLatin1String("SAMEORIGIN")); if (!m_isAltUIUsed) - header(Http::HEADER_REFERRER_POLICY, "same-origin"); + header(QLatin1String(Http::HEADER_REFERRER_POLICY), QLatin1String("same-origin")); + + if (!m_contentSecurityPolicy.isEmpty()) + header(QLatin1String(Http::HEADER_CONTENT_SECURITY_POLICY), m_contentSecurityPolicy); return response(); } diff --git a/src/webui/webapplication.h b/src/webui/webapplication.h index cfe09bcbf..83fc17089 100644 --- a/src/webui/webapplication.h +++ b/src/webui/webapplication.h @@ -157,4 +157,5 @@ private: bool m_isCSRFProtectionEnabled; bool m_isHostHeaderValidationEnabled; bool m_isHttpsEnabled; + QString m_contentSecurityPolicy; };