summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-09-23 16:51:21 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-13 16:41:22 +0200
commit4340b9579e0138dbcde83dc33e3c06c132f432b0 (patch)
treed8f9fac6f7b3787d3a11ba3c7aa6755001f2390c /src/core
parentb99b6ed65f66b4630bdc2b407a97bd0e526165d3 (diff)
Block CORS from local URLs when remote access is not enabled
Task-number: QTBUG-96849 Change-Id: I0e0a1530b8b31341c632a1fd00abd339b5152da0 Reviewed-by: Kirill Burtsev <kirill.burtsev@qt.io> (cherry picked from commit f6f8f258be09fef90585b0228bd82a9708ef34a6)
Diffstat (limited to 'src/core')
-rw-r--r--src/core/net/proxying_url_loader_factory_qt.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp
index 75fc15e6b..883811637 100644
--- a/src/core/net/proxying_url_loader_factory_qt.cpp
+++ b/src/core/net/proxying_url_loader_factory_qt.cpp
@@ -47,8 +47,11 @@
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
#include "net/http/http_status_code.h"
+#include "services/network/public/cpp/cors/cors.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
+#include "url/url_util.h"
#include "api/qwebengineurlrequestinfo_p.h"
#include "type_conversion.h"
@@ -162,6 +165,7 @@ public:
const uint64_t request_id_;
const int32_t routing_id_;
const uint32_t options_;
+ bool allowed_cors_ = true;
// If the |target_loader_| called OnComplete with an error this stores it.
// That way the destructor can send it to OnReceivedError if safe browsing
@@ -204,12 +208,37 @@ InterceptedRequest::InterceptedRequest(ProfileAdapter *profile_adapter,
, target_factory_(std::move(target_factory))
, weak_factory_(this)
{
+ const bool disable_web_security = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebSecurity);
current_response_ = network::mojom::URLResponseHead::New();
+ current_response_->response_type = network::cors::CalculateResponseType(
+ request_.mode,
+ disable_web_security || (
+ request_.request_initiator && request_.request_initiator->IsSameOriginWith(url::Origin::Create(request_.url))));
// If there is a client error, clean up the request.
target_client_.set_disconnect_handler(
base::BindOnce(&InterceptedRequest::OnURLLoaderClientError, base::Unretained(this)));
proxied_loader_receiver_.set_disconnect_with_reason_handler(
base::BindOnce(&InterceptedRequest::OnURLLoaderError, base::Unretained(this)));
+ if (!disable_web_security && request_.request_initiator) {
+ const std::vector<std::string> &localSchemes = url::GetLocalSchemes();
+ std::string fromScheme = request_.request_initiator->GetTupleOrPrecursorTupleIfOpaque().scheme();
+ if (base::Contains(localSchemes, fromScheme)) {
+ content::WebContents *wc = webContents();
+ std::string toScheme = request_.url.scheme();
+ // local schemes must have universal access, or be accessing something local and have local access.
+ if (fromScheme != toScheme) {
+ // note allow_file_access_from_file_urls maps to LocalContentCanAccessFileUrls in our API
+ // and allow_universal_access_from_file_urls to LocalContentCanAccessRemoteUrls, so we are
+ // using them as proxies for our API here.
+ if (toScheme == "file")
+ allowed_cors_ = wc && wc->GetOrCreateWebPreferences().allow_file_access_from_file_urls;
+ else if (!base::Contains(localSchemes, toScheme))
+ allowed_cors_ = wc && wc->GetOrCreateWebPreferences().allow_universal_access_from_file_urls;
+ else
+ allowed_cors_ = true; // We should think about this for future patches
+ }
+ }
+ }
}
InterceptedRequest::~InterceptedRequest()
@@ -246,6 +275,14 @@ void InterceptedRequest::Restart()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ // This is a CORS check on the from URL, the normal check on the to URL is applied later
+ if (!allowed_cors_ && current_response_->response_type == network::mojom::FetchResponseType::kCors) {
+ target_client_->OnComplete(network::URLLoaderCompletionStatus(
+ network::CorsErrorStatus(network::mojom::CorsError::kCorsDisabledScheme)));
+ delete this;
+ return;
+ }
+
// MEMO since all codepatch leading to Restart scheduled and executed as asynchronous tasks in main thread,
// interceptors may change in meantime and also during intercept call, so they should be resolved anew.
// Set here only profile's interceptor since it runs first without going to user code.