Commit 54400200 authored by Mustafa Emre Acer's avatar Mustafa Emre Acer Committed by Commit Bot

Block redirects and renderer-initiated top-frame navigations to filesystem: URLs

Intent to deprecate and remove for renderer-initiated top frame navigations:
https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/X7rZeU93vjw

This CL additionally blocks redirects to filesystem URLs. This matches the redirect
behavior of data URLs.

Bug: 811558
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: I22201825063432ab95872a44aa1925a233e693f5
Reviewed-on: https://chromium-review.googlesource.com/907528
Commit-Queue: Mustafa Emre Acer <meacer@chromium.org>
Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarTaiju Tsuiki <tzik@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554850}
parent f634aa2d
......@@ -1031,27 +1031,53 @@ IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,
EXPECT_EQ(2u, pm->GetAllFrames().size());
}
// From the main frame, create a blank popup and navigate it to each nested
// URL. This should also be allowed, since the navigation originated from an
// extension process.
for (size_t i = 0; i < arraysize(nested_urls); i++) {
// From the main frame, create a blank popup and navigate it to the nested
// blob URL. This should also be allowed, since the navigation originated from
// an extension process.
{
content::WebContents* popup =
OpenPopup(main_frame, GURL(url::kAboutBlankURL));
EXPECT_NE(popup, tab);
content::TestNavigationObserver observer(popup);
EXPECT_TRUE(ExecuteScript(
popup, "location.href = '" + nested_urls[i].spec() + "';"));
popup, "location.href = '" + nested_urls[0].spec() + "';"));
observer.Wait();
EXPECT_EQ(nested_urls[i], popup->GetLastCommittedURL());
EXPECT_EQ(nested_urls[0], popup->GetLastCommittedURL());
EXPECT_EQ(extension_origin,
popup->GetMainFrame()->GetLastCommittedOrigin());
EXPECT_EQ("foo", GetTextContent(popup->GetMainFrame()));
EXPECT_EQ(3 + i,
pm->GetRenderFrameHostsForExtension(extension->id()).size());
EXPECT_EQ(3 + i, pm->GetAllFrames().size());
EXPECT_EQ(3u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
EXPECT_EQ(3u, pm->GetAllFrames().size());
}
// Same as above, but renderers cannot navigate top frame to filesystem URLs.
// So this will result in a console message.
{
content::WebContents* popup =
OpenPopup(main_frame, GURL(url::kAboutBlankURL));
EXPECT_NE(popup, tab);
content::ConsoleObserverDelegate console_observer(
popup, "Not allowed to navigate top frame to*");
popup->SetDelegate(&console_observer);
EXPECT_TRUE(ExecuteScript(
popup, "location.href = '" + nested_urls[1].spec() + "';"));
console_observer.Wait();
// about:blank URLs can be modified by their opener. In that case their
// effective origin changes to that of the opener, but the page URL remains
// about:blank. Here the popup is being modified by the extension page,
// so it's origin will change to the extension URL.
EXPECT_EQ(GURL(url::kAboutBlankURL), popup->GetLastCommittedURL());
EXPECT_EQ(extension_origin,
popup->GetMainFrame()->GetLastCommittedOrigin());
EXPECT_EQ(std::string(), GetTextContent(popup->GetMainFrame()));
EXPECT_EQ(4u, pm->GetRenderFrameHostsForExtension(extension->id()).size());
EXPECT_EQ(4u, pm->GetAllFrames().size());
}
}
......
......@@ -759,10 +759,10 @@ jumbo_source_set("browser") {
"font_list_async.cc",
"frame_host/ancestor_throttle.cc",
"frame_host/ancestor_throttle.h",
"frame_host/blocked_scheme_navigation_throttle.cc",
"frame_host/blocked_scheme_navigation_throttle.h",
"frame_host/cross_process_frame_connector.cc",
"frame_host/cross_process_frame_connector.h",
"frame_host/data_url_navigation_throttle.cc",
"frame_host/data_url_navigation_throttle.h",
"frame_host/debug_urls.cc",
"frame_host/debug_urls.h",
"frame_host/form_submission_throttle.cc",
......
......@@ -683,12 +683,12 @@ bool ChildProcessSecurityPolicyImpl::CanRedirectToURL(const GURL& url) {
// Note about redirects and special URLs:
// * data-url: Blocked by net::DataProtocolHandler::IsSafeRedirectTarget().
// * filesystem-url: Blocked by
// storage::FilesystemProtocolHandler::IsSafeRedirectTarget().
// Depending on their inner origins and if the request is browser-initiated or
// renderer-initiated, blob-urls and filesystem-urls might get blocked by
// CanCommitURL or in DocumentLoader::RedirectReceived.
// * blob-url: If not blocked, a 'file not found' response will be
// generated in net::BlobURLRequestJob::DidStart().
// * filesystem-url: If not blocked, the response is displayed.
// renderer-initiated, blob-urls might get blocked by CanCommitURL or in
// DocumentLoader::RedirectReceived. If not blocked, a 'file not found'
// response will be generated in net::BlobURLRequestJob::DidStart().
return true;
}
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/frame_host/data_url_navigation_throttle.h"
#include "content/browser/frame_host/blocked_scheme_navigation_throttle.h"
#include "base/feature_list.h"
#include "base/strings/stringprintf.h"
......@@ -20,25 +20,25 @@
namespace content {
namespace {
const char kConsoleError[] =
"Not allowed to navigate top frame to data URL: %s";
const char kConsoleError[] = "Not allowed to navigate top frame to %s URL: %s";
}
DataUrlNavigationThrottle::DataUrlNavigationThrottle(
BlockedSchemeNavigationThrottle::BlockedSchemeNavigationThrottle(
NavigationHandle* navigation_handle)
: NavigationThrottle(navigation_handle) {}
DataUrlNavigationThrottle::~DataUrlNavigationThrottle() {}
BlockedSchemeNavigationThrottle::~BlockedSchemeNavigationThrottle() {}
NavigationThrottle::ThrottleCheckResult
DataUrlNavigationThrottle::WillProcessResponse() {
BlockedSchemeNavigationThrottle::WillProcessResponse() {
NavigationHandleImpl* handle =
static_cast<NavigationHandleImpl*>(navigation_handle());
if (handle->IsDownload())
return PROCEED;
// We treat <a download href="data:.."> as a navigation, but it will always
// result in a download, not a top-level navigation, so not blocking it here.
// We treat <a download href="data:.."> and <a download href="filesystem:..">
// as a navigation, but it will always result in a download, not a top-level
// navigation, so not blocking it here.
if (handle->GetSuggestedFilename().has_value())
return PROCEED;
......@@ -46,25 +46,27 @@ DataUrlNavigationThrottle::WillProcessResponse() {
handle->frame_tree_node()->frame_tree()->root()->current_frame_host();
top_frame->AddMessageToConsole(
CONSOLE_MESSAGE_LEVEL_ERROR,
base::StringPrintf(kConsoleError, handle->GetURL().spec().c_str()));
base::StringPrintf(kConsoleError, handle->GetURL().scheme().c_str(),
handle->GetURL().spec().c_str()));
return CANCEL;
}
const char* DataUrlNavigationThrottle::GetNameForLogging() {
return "DataUrlNavigationThrottle";
const char* BlockedSchemeNavigationThrottle::GetNameForLogging() {
return "BlockedSchemeNavigationThrottle";
}
// static
std::unique_ptr<NavigationThrottle>
DataUrlNavigationThrottle::CreateThrottleForNavigation(
BlockedSchemeNavigationThrottle::CreateThrottleForNavigation(
NavigationHandle* navigation_handle) {
if (navigation_handle->IsInMainFrame() &&
navigation_handle->IsRendererInitiated() &&
!navigation_handle->IsSameDocument() &&
navigation_handle->GetURL().SchemeIs(url::kDataScheme) &&
(navigation_handle->GetURL().SchemeIs(url::kDataScheme) ||
navigation_handle->GetURL().SchemeIs(url::kFileSystemScheme)) &&
!base::FeatureList::IsEnabled(
features::kAllowContentInitiatedDataUrlNavigations)) {
return std::make_unique<DataUrlNavigationThrottle>(navigation_handle);
return std::make_unique<BlockedSchemeNavigationThrottle>(navigation_handle);
}
return nullptr;
}
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_FRAME_HOST_DATA_URL_NAVIGATION_THROTTLE_
#define CONTENT_BROWSER_FRAME_HOST_DATA_URL_NAVIGATION_THROTTLE_
#ifndef CONTENT_BROWSER_FRAME_HOST_BLOCKED_SCHEME_NAVIGATION_THROTTLE_H_
#define CONTENT_BROWSER_FRAME_HOST_BLOCKED_SCHEME_NAVIGATION_THROTTLE_H_
#include <memory>
......@@ -12,10 +12,12 @@
namespace content {
class DataUrlNavigationThrottle : public NavigationThrottle {
// Blocks renderer-initiated top-frame navigations to certain URL schemes
// (currently data: and filesystem:).
class BlockedSchemeNavigationThrottle : public NavigationThrottle {
public:
explicit DataUrlNavigationThrottle(NavigationHandle* navigation_handle);
~DataUrlNavigationThrottle() override;
explicit BlockedSchemeNavigationThrottle(NavigationHandle* navigation_handle);
~BlockedSchemeNavigationThrottle() override;
// NavigationThrottle method:
ThrottleCheckResult WillProcessResponse() override;
......@@ -25,9 +27,9 @@ class DataUrlNavigationThrottle : public NavigationThrottle {
NavigationHandle* navigation_handle);
private:
DISALLOW_COPY_AND_ASSIGN(DataUrlNavigationThrottle);
DISALLOW_COPY_AND_ASSIGN(BlockedSchemeNavigationThrottle);
};
} // namespace content
#endif // CONTENT_BROWSER_FRAME_HOST_DATA_URL_NAVIGATION_THROTTLE_
#endif // CONTENT_BROWSER_FRAME_HOST_BLOCKED_SCHEME_NAVIGATION_THROTTLE_H_
......@@ -13,7 +13,7 @@
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/frame_host/ancestor_throttle.h"
#include "content/browser/frame_host/data_url_navigation_throttle.h"
#include "content/browser/frame_host/blocked_scheme_navigation_throttle.h"
#include "content/browser/frame_host/debug_urls.h"
#include "content/browser/frame_host/form_submission_throttle.h"
#include "content/browser/frame_host/frame_tree_node.h"
......@@ -1281,9 +1281,11 @@ void NavigationHandleImpl::RegisterNavigationThrottles() {
// Enforce rules for WebUI navigations.
AddThrottle(WebUINavigationThrottle::CreateThrottleForNavigation(this));
// Check for renderer-inititated main frame navigations to data URLs. This is
// done first as it may block the main frame navigation altogether.
AddThrottle(DataUrlNavigationThrottle::CreateThrottleForNavigation(this));
// Check for renderer-inititated main frame navigations to blocked URL schemes
// (data, filesystem). This is done early as it may block the main frame
// navigation altogether.
AddThrottle(
BlockedSchemeNavigationThrottle::CreateThrottleForNavigation(this));
AddThrottle(AncestorThrottle::MaybeCreateThrottleFor(this));
AddThrottle(FormSubmissionThrottle::MaybeCreateThrottleFor(this));
......
......@@ -732,7 +732,7 @@ test("content_browsertests") {
"../browser/fileapi/file_system_browsertest.cc",
"../browser/fileapi/fileapi_browsertest.cc",
"../browser/find_request_manager_browsertest.cc",
"../browser/frame_host/data_url_navigation_browsertest.cc",
"../browser/frame_host/blocked_scheme_navigation_browsertest.cc",
"../browser/frame_host/form_submission_throttle_browsertest.cc",
"../browser/frame_host/frame_tree_browsertest.cc",
"../browser/frame_host/interstitial_page_impl_browsertest.cc",
......@@ -1182,9 +1182,9 @@ test("content_browsertests") {
# can inspect.
"../browser/media/media_color_browsertest.cc",
# The cast shell has plugin support but no pdf, causing data URL PDF tests
# to fail.
"../browser/frame_host/data_url_navigation_browsertest.cc",
# The cast shell has plugin support but no pdf, causing blocked scheme PDF
# tests to fail.
"../browser/frame_host/blocked_scheme_navigation_browsertest.cc",
# The multi-window tests don't work on cast_shell. Since there's little
# added value in running the single-window test on this platform, just
......
......@@ -2,6 +2,8 @@
<h3>HTML mimetype</h3>
<a download href="data:text/html,download" id="download-link">&lt;a download link&gt;</a>
<br><br>
<button id='navigate-top-frame-to-html'
onclick='top.location.href=`data:text/html,
<script>console.log(&quot;NAVIGATION_SUCCESSFUL&quot;)</script>`'>
......@@ -101,5 +103,8 @@
<input type=submit id='form-post-to-unknown-mimetype'
value='Submit form to data URL unknown mimetype'>
</form>
<script>
if (window.domAutomationController)
window.domAutomationController.send("READY");
</script>
</html>
<html>
<body onload="setupHandlers()">
<h3>HTML mimetype</h3>
<a download id="download-link">&lt;a download link&gt;</a>
<br><br>
<button id='navigate-top-frame-to-html'>
Navigate top frame to filesystem URL HTML
</button>
<br>
<button id='window-open-html'>
Open new window with a filesystem URL HTML
</button>
<button id='window-open-redirect'>
Open new window with a redirect to filesystem URL
</button>
<br>
<form method="post" id="form-post-to-html-form">
<input type=submit id='form-post-to-html'
value="Submit form to filesystem URL HTML">
</form>
<h3>octet-stream mimetype</h3>
<button id='navigate-top-frame-to-octetstream'>
Navigate top frame to filesystem URL octet-stream
</button>
<br>
<button id='window-open-octetstream'>
Open new window with a filesystem URL octet-stream
</button>
<form method="post" id="form-post-to-octetstream-form">
<input type=submit id="form-post-to-octetstream"
value="Submit form to filesystem URL octet-stream">
</form>
<h3>PDF mimetype</h3>
<button id='navigate-top-frame-to-pdf'>
Navigate top frame to filesystem URL PDF
</button>
<br>
<button id='window-open-pdf'>
Open new window with a filesystem URL PDF
</button>
<br>
<form method="post" id="form-post-to-pdf-form">
<input type=submit id='form-post-to-pdf'
value="Submit form to filesystem URL PDF">
</form>
<h3>Unknown mimetype</h3>
<button id='navigate-top-frame-to-unknown-mimetype'>
Navigate top frame to filesystem URL unknown mimetype
</button>
<br>
<button id="window-open-unknown-mimetype">
Open new window with a filesystem URL unknown mimetype
</button>
<form method="post" id="form-post-to-unknown-mimetype-form">
<input type=submit id='form-post-to-unknown-mimetype'
value='Submit form to filesystem URL unknown mimetype'>
</form>
<script>
var PDF =
"%PDF-1.7\n" +
"1 0 obj << /Type /Page /Parent 3 0 R /Resources 5 0 R /Contents 2 0 R >>\n" +
"endobj\n" +
"2 0 obj << /Length 51 >>\n" +
" stream BT\n" +
" /F1 12 Tf\n" +
" 1 0 0 1 100 20 Tm\n" +
" (Hello World)Tj\n" +
" ET\n" +
" endstream\n" +
"endobj\n" +
"3 0 obj << /Type /Pages /Kids [ 1 0 R ] /Count 1 /MediaBox [ 0 0 300 50] >>\n" +
"endobj\n" +
"4 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont/Arial >>\n" +
"endobj\n" +
"5 0 obj << /ProcSet[/PDF/Text] /Font <</F1 4 0 R >> >>\n" +
"endobj\n" +
"6 0 obj << /Type /Catalog /Pages 3 0 R >>\n" +
"endobj\n" +
"trailer << /Root 6 0 R >>";
function setupHandlers() {
window.webkitRequestFileSystem(window.TEMPORARY, 1024, fs => {
// HTML mime type:
fs.root.getFile('test.html', {create: true}, entry => {
entry.createWriter(w => {
w.write(new Blob([
"NAVIGATION_SUCCESSFUL" +
"<script" + ">console.log('NAVIGATION_SUCCESSFUL')<" + "/script>"],
{type: "text/html"}));
});
document.getElementById("download-link").href = entry.toURL();
document.getElementById("navigate-top-frame-to-html").onclick = function() {
top.location.href = entry.toURL();
};
document.getElementById("window-open-html").onclick = function() {
window.open(entry.toURL());
};
document.getElementById("window-open-redirect").onclick = function() {
window.open("/server-redirect?" + entry.toURL());
};
document.getElementById("form-post-to-html-form").action = entry.toURL();
// PDF:
fs.root.getFile('test.pdf', {create: true}, entry => {
entry.createWriter(w => {
var blob = new Blob([PDF], {type: "application/pdf"});
w.write(blob);
});
document.getElementById("navigate-top-frame-to-pdf").onclick = function() {
top.location.href = entry.toURL();
};
document.getElementById("window-open-pdf").onclick = function() {
window.open(entry.toURL());
};
document.getElementById("form-post-to-pdf-form").action = entry.toURL();
// Binary mime type:
fs.root.getFile('test.binary', {create: true}, entry => {
entry.createWriter(w => {
w.write(new Blob(["testdata"], {type: "application/octet-stream"}));
});
document.getElementById("navigate-top-frame-to-octetstream").onclick = function() {
top.location.href = entry.toURL();
};
document.getElementById("window-open-octetstream").onclick = function() {
window.open(entry.toURL());
};
document.getElementById("form-post-to-octetstream-form").action = entry.toURL();
// Unknown mime type:
fs.root.getFile('test.unknown', {create: true}, entry => {
entry.createWriter(w => {
w.write(new Blob(["test"], {type: "unknown/mimetype"}));
});
document.getElementById("navigate-top-frame-to-unknown-mimetype").onclick = function() {
top.location.href = entry.toURL();
};
document.getElementById("window-open-unknown-mimetype").onclick = function() {
window.open(entry.toURL());
};
document.getElementById("form-post-to-unknown-mimetype-form").action = entry.toURL();
if (window.domAutomationController)
window.domAutomationController.send("READY");
});
});
});
});
});
}
</script>
</body>
</html>
......@@ -25,6 +25,10 @@ class FileSystemProtocolHandler
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override;
bool IsSafeRedirectTarget(const GURL& location) const override {
return false;
}
private:
const std::string storage_domain_;
......
......@@ -74,6 +74,20 @@
# https://crbug.com/819663.
-WebContentsImplBrowserTest.UpdateLoadState
# Fails because of missing support to navigate to filesystem: URLs.
# https://crbug.com/797292
-BlockedSchemeNavigationBrowserTest.BrowserInitiated_Allow/1
-BlockedSchemeNavigationBrowserTest.HTML_FormPost_SameScheme_Block/1
-BlockedSchemeNavigationBrowserTest.HTML_Navigation_SameScheme_Block/1
-BlockedSchemeNavigationBrowserTest.HTML_NavigationFromFrame_TopFrameHasBlockedScheme_Block/1
-BlockedSchemeNavigationBrowserTest.HTML_WindowOpenFromFrame_TopFrameHasBlockedScheme_Block/1
-BlockedSchemeNavigationBrowserTest.OctetStream_BrowserInitiated/1
-BlockedSchemeNavigationBrowserTest.PDF_BrowserInitiatedNavigation_Allow/1
-BlockedSchemeNavigationBrowserTest.PDF_NavigationFromFrame_TopFrameHasBlockedScheme_Block/1
-BlockedSchemeNavigationBrowserTest.PDF_WindowOpenFromFrame_TopFrameHasBlockedScheme_Block/1
-BlockedSchemeNavigationBrowserTest.UnknownMimeType_BrowserInitiated_Download/1
-BlockedSchemeNavigationBrowserTest.WindowOpenRedirectAndBack/1
# NOTE: if adding an exclusion for an existing failure (e.g. additional test for
# feature X that is already not working), please add it beside the existing
# failures. Otherwise please reach out to network-service-dev@.
......@@ -8,9 +8,6 @@
</head>
<body>
<script>
// The filesystem test takes some nesting to setup:
setup({explicit_done: true});
async_test(t => {
assert_blocked_image_in_document(t, document, "http://example.test:8000/resources/square.png?img-in-top-level");
}, "Image loaded in top-level blocked.");
......@@ -28,28 +25,7 @@
};
}, "Image loaded via 'blob:' window blocked.");
async_test(t => {
window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, fs => {
fs.root.getFile('worker.js', { create: true }, entry => {
entry.createWriter(w => {
w.onwriteend = _ => {
var w = window.open(entry.toURL());
w.onload = _ => {
assert_blocked_image_in_document(t, w.document, "http://example.test:8000/resources/square.png?img-in-filsystem-window");
};
// explicit_done: yay.
done();
};
w.onerror = t.unreached_func();
var b = new Blob([], {type: "text/html"});
w.write(b);
});
});
});
}, "Image loaded via 'filesystem:' window blocked.");
// filesystem URLs can no longer be window.open'ed.
</script>
</body>
</html>
......@@ -8,9 +8,6 @@
</head>
<body>
<script>
// The filesystem test takes some nesting to setup:
setup({explicit_done: true});
async_test(t => {
assert_allowed_image_in_document(t, document, "http://127.0.0.1:8000/resources/square.png?top-level");
assert_allowed_image_in_document(t, document, "http://example.test:8000/resources/square.png?top-level");
......@@ -33,29 +30,7 @@
};
}, "Image loaded via 'blob:' window blocked.");
async_test(t => {
window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, fs => {
fs.root.getFile('worker.js', { create: true }, entry => {
entry.createWriter(w => {
w.onwriteend = _ => {
var w = window.open(entry.toURL());
w.onload = _ => {
w.document.head.innerHTML = "<meta http-equiv='content-security-policy' content='img-src http://127.0.0.1:8000'>";
assert_allowed_image_in_document(t, w.document, "http://127.0.0.1:8000/resources/square.png?filesystem-frame");
assert_blocked_image_in_document(t, w.document, "http://example.test:8000/resources/square.png?filesystem-frame");
};
// explicit_done: yay.
done();
};
w.onerror = t.unreached_func();
var b = new Blob([], {type: "text/html"});
w.write(b);
});
});
});
}, "Image loaded via 'filesystem:' window blocked.");
// filesystem URLs can no longer be window.open'ed.
</script>
</body>
</html>
......@@ -743,21 +743,26 @@ bool FrameLoader::PrepareRequestForThisFrame(FrameLoadRequest& request) {
return false;
}
// Block renderer-initiated loads of data URLs in the top frame. If the mime
// type of the data URL is supported, the URL will eventually be rendered, so
// block it here. Otherwise, the load might be handled by a plugin or end up
// as a download, so allow it to let the embedder figure out what to do with
// it.
// Block renderer-initiated loads of data: and filesystem: URLs in the top
// frame.
//
// If the mime type of the data URL is supported, the URL will
// eventually be rendered, so block it here. Otherwise, the load might be
// handled by a plugin or end up as a download, so allow it to let the
// embedder figure out what to do with it. Navigations to filesystem URLs are
// always blocked here.
if (frame_->IsMainFrame() &&
!request.GetResourceRequest().IsSameDocumentNavigation() &&
!frame_->Client()->AllowContentInitiatedDataUrlNavigations(
request.OriginDocument()->Url()) &&
!request.GetResourceRequest().GetSuggestedFilename().has_value() &&
url.ProtocolIsData() && NetworkUtils::IsDataURLMimeTypeSupported(url)) {
(url.ProtocolIs("filesystem") ||
(url.ProtocolIsData() &&
NetworkUtils::IsDataURLMimeTypeSupported(url)))) {
frame_->GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
kSecurityMessageSource, kErrorMessageLevel,
"Not allowed to navigate top frame to data URL: " +
url.ElidedString()));
"Not allowed to navigate top frame to " + url.Protocol() +
" URL: " + url.ElidedString()));
return false;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment