Skip to content

Commit

Permalink
Add Chromium-Untrusted Support
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon-T committed Nov 19, 2024
1 parent 044184f commit 551921f
Show file tree
Hide file tree
Showing 20 changed files with 872 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2024 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

// URLRequestJobFactory::CreateJob checks the protocol_handler_map_
// to see what requests can be handled
// The FactoryForMain contains the ProtocolHandlerMap
// This is initialized via ProfileIOSIOData::Init(ProtocolHandlerMap*
// protocol_handlers) Which is called via ProfileIOS::GetRequestContext

#include "ios/chrome/browser/shared/model/profile/profile_ios.h"

#include "ios/components/webui/web_ui_url_constants.h"
#include "ios/web/webui/url_data_manager_ios_backend.h"

// Add the chrome-untrusted scheme
auto CreateRequestContext_Brave(ProfileIOS* profile) {
return [profile](ProtocolHandlerMap* protocol_handlers) {
protocol_handlers->insert(
{kChromeUIUntrustedScheme,
web::URLDataManagerIOSBackend::CreateProtocolHandler(profile)});
return profile->CreateRequestContext(protocol_handlers);
};
}

#define CreateRequestContext CreateRequestContext_Brave(this)

#include "src/ios/chrome/browser/shared/model/profile/profile_ios.mm"

#undef CreateRequestContext
8 changes: 8 additions & 0 deletions chromium_src/ios/components/webui/web_ui_url_constants.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* Copyright (c) 2024 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "src/ios/components/webui/web_ui_url_constants.cc"

const char kChromeUIUntrustedScheme[] = "chrome-untrusted";
13 changes: 13 additions & 0 deletions chromium_src/ios/components/webui/web_ui_url_constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* Copyright (c) 2024 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_CHROMIUM_SRC_IOS_COMPONENTS_WEBUI_WEB_UI_URL_CONSTANTS_H_
#define BRAVE_CHROMIUM_SRC_IOS_COMPONENTS_WEBUI_WEB_UI_URL_CONSTANTS_H_

extern const char kChromeUIUntrustedScheme[];

#include "src/ios/components/webui/web_ui_url_constants.h" // IWYU pragma: export

#endif // BRAVE_CHROMIUM_SRC_IOS_COMPONENTS_WEBUI_WEB_UI_URL_CONSTANTS_H_
35 changes: 35 additions & 0 deletions chromium_src/ios/web/public/webui/url_data_source_ios.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* Copyright (c) 2024 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_CHROMIUM_SRC_IOS_WEB_PUBLIC_WEBUI_URL_DATA_SOURCE_IOS_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_PUBLIC_WEBUI_URL_DATA_SOURCE_IOS_H_

#include <cstdint>

namespace network::mojom {
enum class CSPDirectiveName : std::int32_t;
} // namespace network::mojom

#define GetContentSecurityPolicyObjectSrc \
GetContentSecurityPolicyObjectSrc_ChromiumImpl() const; \
virtual std::string GetContentSecurityPolicyObjectSrc

#define ShouldServiceRequest \
ShouldServiceRequest_ChromiumImpl(const GURL& url) const; \
virtual bool ShouldServiceRequest(const GURL& url) const; \
virtual bool ShouldAddContentSecurityPolicy() const; \
virtual std::string GetContentSecurityPolicyFrameSrc() const; \
virtual std::string GetContentSecurityPolicy( \
network::mojom::CSPDirectiveName directive) const; \
\
private: \
bool Dummy

#import "src/ios/web/public/webui/url_data_source_ios.h" // IWYU pragma: export

#undef GetContentSecurityPolicyObjectSrc
#undef ShouldServiceRequest

#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_PUBLIC_WEBUI_URL_DATA_SOURCE_IOS_H_
27 changes: 27 additions & 0 deletions chromium_src/ios/web/public/webui/web_ui_ios_data_source.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* Copyright (c) 2024 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_CHROMIUM_SRC_IOS_WEB_PUBLIC_WEBUI_WEB_UI_IOS_DATA_SOURCE_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_PUBLIC_WEBUI_WEB_UI_IOS_DATA_SOURCE_H_

#include <cstdint>

namespace network::mojom {
enum class CSPDirectiveName : std::int32_t;
} // namespace network::mojom

#define DisableDenyXFrameOptions \
DisableDenyXFrameOptions() = 0; \
virtual void OverrideContentSecurityPolicy( \
network::mojom::CSPDirectiveName directive, \
const std::string& value) = 0; \
virtual void AddFrameAncestor(const GURL& frame_ancestor) = 0; \
virtual void DisableTrustedTypesCSP

#include "src/ios/web/public/webui/web_ui_ios_data_source.h" // IWYU pragma: export

#undef DisableDenyXFrameOptions

#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_PUBLIC_WEBUI_WEB_UI_IOS_DATA_SOURCE_H_
8 changes: 8 additions & 0 deletions chromium_src/ios/web/webui/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2024 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at https://mozilla.org/MPL/2.0/.

source_set("webui") {
deps = [ "//ios/components/webui:web_ui_url_constants" ]
}
3 changes: 3 additions & 0 deletions chromium_src/ios/web/webui/DEPS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include_rules = [
"+ios/components/webui/web_ui_url_constants.h",
]
19 changes: 19 additions & 0 deletions chromium_src/ios/web/webui/url_data_manager_ios_backend.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* Copyright (c) 2024 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "ios/web/webui/url_data_manager_ios_backend.h"

#define ShouldDenyXFrameOptions ShouldDenyXFrameOptions()); \
job->set_add_content_security_policy( \
source->source()->ShouldAddContentSecurityPolicy()); \
job->set_content_security_policy_object_source( \
source->source()->GetContentSecurityPolicyObjectSrc()); \
job->set_content_security_policy_frame_source( \
source->source()->GetContentSecurityPolicyFrameSrc()); \
void(void

#include "src/ios/web/webui/url_data_manager_ios_backend.mm"

#undef ShouldDenyXFrameOptions
153 changes: 153 additions & 0 deletions chromium_src/ios/web/webui/url_data_source_ios.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Copyright (c) 2024 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

#include "ios/web/public/webui/url_data_source_ios.h"

#include "base/containers/span.h"
#include "base/no_destructor.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "ios/components/webui/web_ui_url_constants.h"
#include "services/network/public/mojom/content_security_policy.mojom.h"

namespace {

// A chrome-untrusted data source's name starts with chrome-untrusted://.
bool IsChromeUntrustedDataSource(const web::URLDataSourceIOS* source) {
static const base::NoDestructor<std::string> kChromeUntrustedSourceNamePrefix(
base::StrCat({kChromeUIUntrustedScheme, url::kStandardSchemeSeparator}));

return base::StartsWith(source->GetSource(),
*kChromeUntrustedSourceNamePrefix,
base::CompareCase::SENSITIVE);
}

} // namespace

namespace web {
bool URLDataSourceIOS::ShouldAddContentSecurityPolicy() const {
return true;
}

bool URLDataSourceIOS::ShouldServiceRequest(const GURL& url) const {
return URLDataSourceIOS::ShouldServiceRequest_ChromiumImpl(url);
}

std::string URLDataSourceIOS::GetContentSecurityPolicyObjectSrc() const {
if (ShouldAddContentSecurityPolicy()) {
std::string csp_header;

const network::mojom::CSPDirectiveName kAllDirectives[] = {
network::mojom::CSPDirectiveName::BaseURI,
network::mojom::CSPDirectiveName::ChildSrc,
network::mojom::CSPDirectiveName::ConnectSrc,
network::mojom::CSPDirectiveName::DefaultSrc,
network::mojom::CSPDirectiveName::FencedFrameSrc,
network::mojom::CSPDirectiveName::FormAction,
network::mojom::CSPDirectiveName::FontSrc,
network::mojom::CSPDirectiveName::ImgSrc,
network::mojom::CSPDirectiveName::MediaSrc,
network::mojom::CSPDirectiveName::ObjectSrc,
network::mojom::CSPDirectiveName::RequireTrustedTypesFor,
network::mojom::CSPDirectiveName::ScriptSrc,
network::mojom::CSPDirectiveName::StyleSrc,
network::mojom::CSPDirectiveName::TrustedTypes,
network::mojom::CSPDirectiveName::WorkerSrc};

for (auto& directive : kAllDirectives) {
csp_header.append(GetContentSecurityPolicy(directive));
}

// TODO(crbug.com/40118579): Both CSP frame ancestors and XFO headers may be
// added to the response but frame ancestors would take precedence. In the
// future, XFO will be removed so when that happens remove the check and
// always add frame ancestors.
if (ShouldDenyXFrameOptions()) {
csp_header.append(GetContentSecurityPolicy(
network::mojom::CSPDirectiveName::FrameAncestors));
}

return csp_header;
}

return URLDataSourceIOS::GetContentSecurityPolicyObjectSrc_ChromiumImpl();
}

std::string URLDataSourceIOS::GetContentSecurityPolicyFrameSrc() const {
std::string frame_src =
GetContentSecurityPolicy(network::mojom::CSPDirectiveName::FrameSrc);
if (!frame_src.empty()) {
return frame_src;
}

return "frame-src 'none';";
}

std::string URLDataSourceIOS::GetContentSecurityPolicy(
network::mojom::CSPDirectiveName directive) const {
switch (directive) {
case network::mojom::CSPDirectiveName::ChildSrc:
return "child-src 'none';";
case network::mojom::CSPDirectiveName::DefaultSrc:
return IsChromeUntrustedDataSource(this) ? "default-src 'self';"
: std::string();
case network::mojom::CSPDirectiveName::ObjectSrc:
return "object-src 'none';";
case network::mojom::CSPDirectiveName::ScriptSrc:
// Note: Do not add 'unsafe-eval' here. Instead override CSP for the
// specific pages that need it, see context http://crbug.com/525224.
return IsChromeUntrustedDataSource(this)
? base::StrCat({"script-src", kChromeUIUntrustedScheme,
url::kStandardSchemeSeparator,
"resources 'self';"})
: "script-src chrome://resources 'self';";
case network::mojom::CSPDirectiveName::FrameAncestors:
return "frame-ancestors 'none';";
case network::mojom::CSPDirectiveName::RequireTrustedTypesFor:
return "require-trusted-types-for 'script';";
case network::mojom::CSPDirectiveName::TrustedTypes:
return "trusted-types;";
case network::mojom::CSPDirectiveName::BaseURI:
return IsChromeUntrustedDataSource(this) ? "base-uri 'none';"
: std::string();
case network::mojom::CSPDirectiveName::FormAction:
return IsChromeUntrustedDataSource(this) ? "form-action 'none';"
: std::string();
case network::mojom::CSPDirectiveName::BlockAllMixedContent:
case network::mojom::CSPDirectiveName::ConnectSrc:
case network::mojom::CSPDirectiveName::FencedFrameSrc:
case network::mojom::CSPDirectiveName::FrameSrc:
case network::mojom::CSPDirectiveName::FontSrc:
case network::mojom::CSPDirectiveName::ImgSrc:
case network::mojom::CSPDirectiveName::ManifestSrc:
case network::mojom::CSPDirectiveName::MediaSrc:
case network::mojom::CSPDirectiveName::ReportURI:
case network::mojom::CSPDirectiveName::Sandbox:
case network::mojom::CSPDirectiveName::ScriptSrcAttr:
case network::mojom::CSPDirectiveName::ScriptSrcElem:
case network::mojom::CSPDirectiveName::StyleSrc:
case network::mojom::CSPDirectiveName::StyleSrcAttr:
case network::mojom::CSPDirectiveName::StyleSrcElem:
case network::mojom::CSPDirectiveName::UpgradeInsecureRequests:
case network::mojom::CSPDirectiveName::TreatAsPublicAddress:
case network::mojom::CSPDirectiveName::WorkerSrc:
case network::mojom::CSPDirectiveName::ReportTo:
case network::mojom::CSPDirectiveName::Unknown:
return std::string();
}
}

} // namespace web

#define GetContentSecurityPolicyObjectSrc \
GetContentSecurityPolicyObjectSrc_ChromiumImpl

#define ShouldServiceRequest ShouldServiceRequest_ChromiumImpl

#include "src/ios/web/webui/url_data_source_ios.mm"

#undef ShouldServiceRequest
#undef GetContentSecurityPolicyObjectSrc
35 changes: 35 additions & 0 deletions chromium_src/ios/web/webui/web_ui_ios_data_source_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* Copyright (c) 2024 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_CHROMIUM_SRC_IOS_WEB_WEBUI_WEB_UI_IOS_DATA_SOURCE_IMPL_H_
#define BRAVE_CHROMIUM_SRC_IOS_WEB_WEBUI_WEB_UI_IOS_DATA_SOURCE_IMPL_H_

#include <cstdint>
#include <set>

namespace network::mojom {
enum class CSPDirectiveName : std::int32_t;
} // namespace network::mojom

#define should_replace_i18n_in_js_ \
should_replace_i18n_in_js_; \
\
public: \
void OverrideContentSecurityPolicy( \
network::mojom::CSPDirectiveName directive, const std::string& value) \
override; \
void AddFrameAncestor(const GURL& frame_ancestor) override; \
void DisableTrustedTypesCSP() override; \
\
private: \
base::flat_map<network::mojom::CSPDirectiveName, std::string> \
csp_overrides_; \
std::set<GURL> frame_ancestors_

#include "src/ios/web/webui/web_ui_ios_data_source_impl.h" // IWYU pragma: export

#undef should_replace_i18n_in_js_

#endif // BRAVE_CHROMIUM_SRC_IOS_WEB_WEBUI_WEB_UI_IOS_DATA_SOURCE_IMPL_H_
Loading

0 comments on commit 551921f

Please sign in to comment.