diff --git a/atom/app/atom_content_client.cc b/atom/app/atom_content_client.cc index 40a6e1f5268dd..a49b39e45cf3e 100644 --- a/atom/app/atom_content_client.cc +++ b/atom/app/atom_content_client.cc @@ -197,11 +197,20 @@ void AtomContentClient::AddServiceWorkerSchemes( std::vector schemes; ConvertStringWithSeparatorToVector(&schemes, ",", switches::kRegisterServiceWorkerSchemes); - if (!schemes.empty()) { - for (const std::string& scheme : schemes) - service_worker_schemes->insert(scheme); - } + for (const std::string& scheme : schemes) + service_worker_schemes->insert(scheme); + service_worker_schemes->insert(url::kFileScheme); } +void AtomContentClient::AddSecureSchemesAndOrigins( + std::set* secure_schemes, + std::set* secure_origins) { + std::vector schemes; + ConvertStringWithSeparatorToVector(&schemes, ",", switches::kSecureSchemes); + for (const std::string& scheme : schemes) + secure_schemes->insert(scheme); +} + + } // namespace atom diff --git a/atom/app/atom_content_client.h b/atom/app/atom_content_client.h index f31a14605723c..e396dc23c8e93 100644 --- a/atom/app/atom_content_client.h +++ b/atom/app/atom_content_client.h @@ -31,6 +31,9 @@ class AtomContentClient : public brightray::ContentClient { std::vector* plugins) override; void AddServiceWorkerSchemes( std::set* service_worker_schemes) override; + void AddSecureSchemesAndOrigins( + std::set* secure_schemes, + std::set* secure_origins) override; private: DISALLOW_COPY_AND_ASSIGN(AtomContentClient); diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index fd2485063a2ae..e3b15ed432938 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -46,7 +46,8 @@ std::vector GetStandardSchemes() { return g_standard_schemes; } -void RegisterStandardSchemes(const std::vector& schemes) { +void RegisterStandardSchemes(const std::vector& schemes, + mate::Arguments* args) { g_standard_schemes = schemes; auto* policy = content::ChildProcessSecurityPolicy::GetInstance(); @@ -55,8 +56,17 @@ void RegisterStandardSchemes(const std::vector& schemes) { policy->RegisterWebSafeScheme(scheme); } + // add switches to register as standard base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( atom::switches::kStandardSchemes, base::JoinString(schemes, ",")); + + mate::Dictionary opts; + bool secure = false; + if (args->GetNext(&opts) && opts.Get("secure", &secure) && secure) { + // add switches to register as secure + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + atom::switches::kSecureSchemes, base::JoinString(schemes, ",")); + } } Protocol::Protocol(v8::Isolate* isolate, AtomBrowserContext* browser_context) @@ -220,7 +230,7 @@ void RegisterStandardSchemes( return; } - atom::api::RegisterStandardSchemes(schemes); + atom::api::RegisterStandardSchemes(schemes, args); } void Initialize(v8::Local exports, v8::Local unused, diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index 3ad039c1b8035..dfc32be6bc57c 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -29,7 +29,8 @@ namespace atom { namespace api { std::vector GetStandardSchemes(); -void RegisterStandardSchemes(const std::vector& schemes); +void RegisterStandardSchemes(const std::vector& schemes, + mate::Arguments* args); class Protocol : public mate::TrackableObject { public: diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 030ad1402b11d..6734bbfa101eb 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -234,7 +234,8 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( // Copy following switches to child process. static const char* const kCommonSwitchNames[] = { switches::kStandardSchemes, - switches::kEnableSandbox + switches::kEnableSandbox, + switches::kSecureSchemes }; command_line->CopySwitchesFrom( *base::CommandLine::ForCurrentProcess(), diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 70aeccfc9bc7a..30aa48b987d70 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -144,6 +144,9 @@ const char kStandardSchemes[] = "standard-schemes"; // Register schemes to handle service worker. const char kRegisterServiceWorkerSchemes[] = "register-service-worker-schemes"; +// Register schemes as secure. +const char kSecureSchemes[] = "secure-schemes"; + // The minimum SSL/TLS version ("tls1", "tls1.1", or "tls1.2") that // TLS fallback will accept. const char kSSLVersionFallbackMin[] = "ssl-version-fallback-min"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 3c9abebf4ce42..c930cabe34ded 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -76,6 +76,7 @@ extern const char kPpapiFlashVersion[]; extern const char kDisableHttpCache[]; extern const char kStandardSchemes[]; extern const char kRegisterServiceWorkerSchemes[]; +extern const char kSecureSchemes[]; extern const char kSSLVersionFallbackMin[]; extern const char kCipherSuiteBlacklist[]; extern const char kAppUserModelId[]; diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index fcfc50cf7f134..a7b71c35af249 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -133,6 +133,7 @@ void WebFrame::SetSpellCheckProvider(mate::Arguments* args, } void WebFrame::RegisterURLSchemeAsSecure(const std::string& scheme) { + // TODO(pfrazee): Remove 2.0 // Register scheme to secure list (https, wss, data). blink::WebSecurityPolicy::registerURLSchemeAsSecure( blink::WebString::fromUTF8(scheme)); @@ -165,6 +166,7 @@ void WebFrame::RegisterURLSchemeAsPrivileged(const std::string& scheme, // Register scheme to privileged list (https, wss, data, chrome-extension) blink::WebString privileged_scheme(blink::WebString::fromUTF8(scheme)); if (secure) { + // TODO(pfrazee): Remove 2.0 blink::WebSecurityPolicy::registerURLSchemeAsSecure(privileged_scheme); } if (bypassCSP) { diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index c3ad11e1438e0..5f2aec74e3534 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -121,21 +121,23 @@ bool IsDevToolsExtension(content::RenderFrame* render_frame) { .SchemeIs("chrome-extension"); } +std::vector ParseSchemesCLISwitch(const char* switch_name) { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + std::string custom_schemes = command_line->GetSwitchValueASCII(switch_name); + return base::SplitString( + custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); +} + } // namespace AtomRendererClient::AtomRendererClient() : node_bindings_(NodeBindings::Create(false)), atom_bindings_(new AtomBindings) { // Parse --standard-schemes=scheme1,scheme2 - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - std::string custom_schemes = command_line->GetSwitchValueASCII( - switches::kStandardSchemes); - if (!custom_schemes.empty()) { - std::vector schemes_list = base::SplitString( - custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - for (const std::string& scheme : schemes_list) - url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT); - } + std::vector standard_schemes_list = + ParseSchemesCLISwitch(switches::kStandardSchemes); + for (const std::string& scheme : standard_schemes_list) + url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT); } AtomRendererClient::~AtomRendererClient() { @@ -182,6 +184,13 @@ void AtomRendererClient::RenderFrameCreated( // Allow file scheme to handle service worker by default. // FIXME(zcbenz): Can this be moved elsewhere? blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers("file"); + + // Parse --secure-schemes=scheme1,scheme2 + std::vector secure_schemes_list = + ParseSchemesCLISwitch(switches::kSecureSchemes); + for (const std::string& secure_scheme : secure_schemes_list) + blink::WebSecurityPolicy::registerURLSchemeAsSecure( + blink::WebString::fromUTF8(secure_scheme)); } void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) { diff --git a/docs/tutorial/planned-breaking-changes.md b/docs/tutorial/planned-breaking-changes.md index 4e604945ef4db..44b837e619f96 100644 --- a/docs/tutorial/planned-breaking-changes.md +++ b/docs/tutorial/planned-breaking-changes.md @@ -117,6 +117,16 @@ webContents.setVisualZoomLevelLimits(1, 2) webFrame.setZoomLevelLimits(1, 2) // Replace with webFrame.setVisualZoomLevelLimits(1, 2) + +// Deprecated +webFrame.registerURLSchemeAsSecure('app') +// Replace with +protocol.registerStandardSchemes(['app'], {secure: true}) + +// Deprecated +webFrame.registerURLSchemeAsPrivileged('app', {secure: true}) +// Replace with +protocol.registerStandardSchemes(['app'], {secure: true}) ``` ## `` diff --git a/spec/api-protocol-spec.js b/spec/api-protocol-spec.js index 51003ebf427ad..7781706b810dc 100644 --- a/spec/api-protocol-spec.js +++ b/spec/api-protocol-spec.js @@ -985,5 +985,19 @@ describe('protocol module', function () { ipcMain.once('file-system-error', (event, err) => done(err)) ipcMain.once('file-system-write-end', () => done()) }) + + it('registers secure, when {secure: true}', function (done) { + // the CacheStorage API will only work if secure == true + let filePath = path.join(__dirname, 'fixtures', 'pages', 'cache-storage.html') + const handler = function (request, callback) { + callback({path: filePath}) + } + ipcMain.once('success', () => done()) + ipcMain.once('failure', (event, err) => done(err)) + protocol.registerFileProtocol(standardScheme, handler, function (error) { + if (error) return done(error) + w.loadURL(origin) + }) + }) }) }) diff --git a/spec/fixtures/pages/cache-storage.html b/spec/fixtures/pages/cache-storage.html new file mode 100644 index 0000000000000..0b6717201e50e --- /dev/null +++ b/spec/fixtures/pages/cache-storage.html @@ -0,0 +1,7 @@ + diff --git a/spec/static/main.js b/spec/static/main.js index f29cbebeeb1e3..1b512e1b0dbf4 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -92,7 +92,7 @@ if (global.isCi) { // Register app as standard scheme. global.standardScheme = 'app' -protocol.registerStandardSchemes([global.standardScheme]) +protocol.registerStandardSchemes([global.standardScheme], { secure: true }) app.on('window-all-closed', function () { app.quit()