OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights |
3 * reserved. | 3 * reserved. |
4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
5 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 5 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
6 * (http://www.torchmobile.com/) | 6 * (http://www.torchmobile.com/) |
7 * Copyright (C) 2008 Alp Toker <alp@atoker.com> | 7 * Copyright (C) 2008 Alp Toker <alp@atoker.com> |
8 * Copyright (C) Research In Motion Limited 2009. All rights reserved. | 8 * Copyright (C) Research In Motion Limited 2009. All rights reserved. |
9 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> | 9 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> |
10 * Copyright (C) 2011 Google Inc. All rights reserved. | 10 * Copyright (C) 2011 Google Inc. All rights reserved. |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 return; | 132 return; |
133 } | 133 } |
134 if (SchemeRegistry::ShouldTreatURLSchemeAsLegacy( | 134 if (SchemeRegistry::ShouldTreatURLSchemeAsLegacy( |
135 document->GetSecurityOrigin()->Protocol())) { | 135 document->GetSecurityOrigin()->Protocol())) { |
136 return; | 136 return; |
137 } | 137 } |
138 Deprecation::CountDeprecation( | 138 Deprecation::CountDeprecation( |
139 document, UseCounter::kLegacyProtocolEmbeddedAsSubresource); | 139 document, UseCounter::kLegacyProtocolEmbeddedAsSubresource); |
140 } | 140 } |
141 | 141 |
142 static NavigationPolicy MaybeCheckCSP( | |
143 const ResourceRequest& request, | |
144 NavigationType type, | |
145 LocalFrame* frame, | |
146 NavigationPolicy policy, | |
147 bool should_check_main_world_content_security_policy, | |
148 bool browser_side_navigation_enabled, | |
149 ContentSecurityPolicy::CheckHeaderType check_header_type) { | |
150 // If we're loading content into |frame| (NavigationPolicyCurrentTab), check | |
151 // against the parent's Content Security Policy and kill the load if that | |
152 // check fails, unless we should bypass the main world's CSP. | |
153 if (policy == kNavigationPolicyCurrentTab && | |
154 should_check_main_world_content_security_policy && | |
155 // TODO(arthursonzogni): 'frame-src' check is disabled on the | |
156 // renderer side with browser-side-navigation, but is enforced on the | |
157 // browser side. See http://crbug.com/692595 for understanding why it | |
158 // can't be enforced on both sides instead. | |
159 !browser_side_navigation_enabled) { | |
160 Frame* parent_frame = frame->Tree().Parent(); | |
161 if (parent_frame) { | |
162 ContentSecurityPolicy* parent_policy = | |
163 parent_frame->GetSecurityContext()->GetContentSecurityPolicy(); | |
164 if (!parent_policy->AllowFrameFromSource( | |
165 request.Url(), request.GetRedirectStatus(), | |
166 SecurityViolationReportingPolicy::kReport, check_header_type)) { | |
167 // Fire a load event, as timing attacks would otherwise reveal that the | |
168 // frame was blocked. This way, it looks like every other cross-origin | |
169 // page load. | |
170 frame->GetDocument()->EnforceSandboxFlags(kSandboxOrigin); | |
171 frame->Owner()->DispatchLoad(); | |
172 return kNavigationPolicyIgnore; | |
173 } | |
174 } | |
175 } | |
176 | |
177 bool is_form_submission = type == kNavigationTypeFormSubmitted || | |
178 type == kNavigationTypeFormResubmitted; | |
179 if (is_form_submission && | |
180 // 'form-action' check in the frame that is navigating is disabled on the | |
181 // renderer side when PlzNavigate is enabled, but is enforced on the | |
182 // browser side instead. | |
183 // N.B. check in the frame that initiates the navigation stills occurs in | |
184 // blink and is not enforced on the browser-side. | |
185 // TODO(arthursonzogni) The 'form-action' check should be fully disabled | |
186 // in blink when browser side navigation is enabled, except when the form | |
187 // submission doesn't trigger a navigation(i.e. javascript urls). Please | |
188 // see https://crbug.com/701749 | |
189 !browser_side_navigation_enabled && | |
190 !frame->GetDocument()->GetContentSecurityPolicy()->AllowFormAction( | |
191 request.Url(), request.GetRedirectStatus(), | |
192 SecurityViolationReportingPolicy::kReport, check_header_type)) { | |
193 return kNavigationPolicyIgnore; | |
194 } | |
195 | |
196 return policy; | |
197 } | |
198 | |
142 ResourceRequest FrameLoader::ResourceRequestForReload( | 199 ResourceRequest FrameLoader::ResourceRequestForReload( |
143 FrameLoadType frame_load_type, | 200 FrameLoadType frame_load_type, |
144 const KURL& override_url, | 201 const KURL& override_url, |
145 ClientRedirectPolicy client_redirect_policy) { | 202 ClientRedirectPolicy client_redirect_policy) { |
146 DCHECK(IsReloadLoadType(frame_load_type)); | 203 DCHECK(IsReloadLoadType(frame_load_type)); |
147 WebCachePolicy cache_policy = | 204 WebCachePolicy cache_policy = |
148 frame_load_type == kFrameLoadTypeReloadBypassingCache | 205 frame_load_type == kFrameLoadTypeReloadBypassingCache |
149 ? WebCachePolicy::kBypassingCache | 206 ? WebCachePolicy::kBypassingCache |
150 : WebCachePolicy::kValidatingCacheData; | 207 : WebCachePolicy::kValidatingCacheData; |
151 if (!document_loader_ || !document_loader_->GetHistoryItem()) | 208 if (!document_loader_ || !document_loader_->GetHistoryItem()) |
(...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1363 NavigationType type, | 1420 NavigationType type, |
1364 NavigationPolicy policy, | 1421 NavigationPolicy policy, |
1365 FrameLoadType frame_load_type, | 1422 FrameLoadType frame_load_type, |
1366 bool is_client_redirect, | 1423 bool is_client_redirect, |
1367 HTMLFormElement* form) { | 1424 HTMLFormElement* form) { |
1368 // Don't ask if we are loading an empty URL. | 1425 // Don't ask if we are loading an empty URL. |
1369 if (request.Url().IsEmpty() || substitute_data.IsValid()) | 1426 if (request.Url().IsEmpty() || substitute_data.IsValid()) |
1370 return kNavigationPolicyCurrentTab; | 1427 return kNavigationPolicyCurrentTab; |
1371 | 1428 |
1372 Settings* settings = frame_->GetSettings(); | 1429 Settings* settings = frame_->GetSettings(); |
1373 bool browser_side_navigation_enabled = | 1430 if (MaybeCheckCSP(request, type, frame_, policy, |
1374 settings && settings->GetBrowserSideNavigationEnabled(); | 1431 should_check_main_world_content_security_policy == |
1375 | 1432 kCheckContentSecurityPolicy, |
1376 // If we're loading content into |m_frame| (NavigationPolicyCurrentTab), check | 1433 settings && settings->GetBrowserSideNavigationEnabled(), |
1377 // against the parent's Content Security Policy and kill the load if that | 1434 ContentSecurityPolicy::CheckHeaderType::kCheckEnforce) == |
1378 // check fails, unless we should bypass the main world's CSP. | 1435 kNavigationPolicyIgnore) { |
1379 if (policy == kNavigationPolicyCurrentTab && | |
1380 should_check_main_world_content_security_policy == | |
1381 kCheckContentSecurityPolicy && | |
1382 // TODO(arthursonzogni): 'frame-src' check is disabled on the | |
1383 // renderer side with browser-side-navigation, but is enforced on the | |
1384 // browser side. See http://crbug.com/692595 for understanding why it | |
1385 // can't be enforced on both sides instead. | |
1386 !browser_side_navigation_enabled) { | |
1387 Frame* parent_frame = frame_->Tree().Parent(); | |
1388 if (parent_frame) { | |
1389 ContentSecurityPolicy* parent_policy = | |
1390 parent_frame->GetSecurityContext()->GetContentSecurityPolicy(); | |
1391 if (!parent_policy->AllowFrameFromSource(request.Url(), | |
1392 request.GetRedirectStatus())) { | |
1393 // Fire a load event, as timing attacks would otherwise reveal that the | |
1394 // frame was blocked. This way, it looks like every other cross-origin | |
1395 // page load. | |
1396 frame_->GetDocument()->EnforceSandboxFlags(kSandboxOrigin); | |
1397 frame_->Owner()->DispatchLoad(); | |
1398 return kNavigationPolicyIgnore; | |
1399 } | |
1400 } | |
1401 } | |
1402 | |
1403 bool is_form_submission = type == kNavigationTypeFormSubmitted || | |
1404 type == kNavigationTypeFormResubmitted; | |
1405 if (is_form_submission && | |
1406 // 'form-action' check in the frame that is navigating is disabled on the | |
1407 // renderer side when PlzNavigate is enabled, but is enforced on the | |
1408 // browser side instead. | |
1409 // N.B. check in the frame that initiates the navigation stills occurs in | |
1410 // blink and is not enforced on the browser-side. | |
1411 // TODO(arthursonzogni) The 'form-action' check should be fully disabled | |
1412 // in blink when browser side navigation is enabled, except when the form | |
1413 // submission doesn't trigger a navigation(i.e. javascript urls). Please | |
1414 // see https://crbug.com/701749 | |
1415 !browser_side_navigation_enabled && | |
1416 !frame_->GetDocument()->GetContentSecurityPolicy()->AllowFormAction( | |
1417 request.Url(), request.GetRedirectStatus())) { | |
1418 return kNavigationPolicyIgnore; | 1436 return kNavigationPolicyIgnore; |
1419 } | 1437 } |
1420 | 1438 |
1421 bool replaces_current_history_item = | 1439 bool replaces_current_history_item = |
1422 frame_load_type == kFrameLoadTypeReplaceCurrentItem; | 1440 frame_load_type == kFrameLoadTypeReplaceCurrentItem; |
1423 policy = Client()->DecidePolicyForNavigation( | 1441 policy = Client()->DecidePolicyForNavigation( |
1424 request, loader, type, policy, replaces_current_history_item, | 1442 request, loader, type, policy, replaces_current_history_item, |
1425 is_client_redirect, form, | 1443 is_client_redirect, form, |
1426 should_check_main_world_content_security_policy); | 1444 should_check_main_world_content_security_policy); |
1427 if (policy == kNavigationPolicyCurrentTab || | 1445 if (policy == kNavigationPolicyCurrentTab || |
1428 policy == kNavigationPolicyIgnore || | 1446 policy == kNavigationPolicyIgnore || |
1429 policy == kNavigationPolicyHandledByClient || | 1447 policy == kNavigationPolicyHandledByClient || |
1430 policy == kNavigationPolicyHandledByClientForInitialHistory) { | 1448 policy == kNavigationPolicyHandledByClientForInitialHistory) { |
1431 return policy; | 1449 return policy; |
1432 } | 1450 } |
1433 | 1451 |
1434 if (!LocalDOMWindow::AllowPopUp(*frame_) && | 1452 if (!LocalDOMWindow::AllowPopUp(*frame_) && |
1435 !UserGestureIndicator::UtilizeUserGesture()) | 1453 !UserGestureIndicator::UtilizeUserGesture()) |
1436 return kNavigationPolicyIgnore; | 1454 return kNavigationPolicyIgnore; |
1437 Client()->LoadURLExternally(request, policy, String(), | 1455 Client()->LoadURLExternally(request, policy, String(), |
1438 replaces_current_history_item); | 1456 replaces_current_history_item); |
1439 return kNavigationPolicyIgnore; | 1457 return kNavigationPolicyIgnore; |
1440 } | 1458 } |
1441 | 1459 |
1460 NavigationPolicy FrameLoader::ShouldContinueForRedirectNavigationPolicy( | |
1461 const ResourceRequest& request, | |
1462 const SubstituteData& substitute_data, | |
1463 DocumentLoader* loader, | |
1464 ContentSecurityPolicyDisposition | |
1465 should_check_main_world_content_security_policy, | |
1466 NavigationType type, | |
1467 NavigationPolicy policy, | |
1468 FrameLoadType frame_load_type, | |
1469 bool is_client_redirect, | |
1470 HTMLFormElement* form) { | |
1471 Settings* settings = frame_->GetSettings(); | |
1472 // Check report-only CSP policies, which are not checked by | |
1473 // ShouldContinueForNavigationPolicy. | |
1474 MaybeCheckCSP(request, type, frame_, policy, | |
1475 should_check_main_world_content_security_policy == | |
1476 kCheckContentSecurityPolicy, | |
1477 settings && settings->GetBrowserSideNavigationEnabled(), | |
1478 ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly); | |
1479 return ShouldContinueForNavigationPolicy( | |
1480 request, substitute_data, loader, | |
1481 should_check_main_world_content_security_policy, type, policy, | |
1482 frame_load_type, is_client_redirect, form); | |
1483 } | |
1484 | |
1442 NavigationPolicy FrameLoader::CheckLoadCanStart( | 1485 NavigationPolicy FrameLoader::CheckLoadCanStart( |
1443 FrameLoadRequest& frame_load_request, | 1486 FrameLoadRequest& frame_load_request, |
1444 FrameLoadType type, | 1487 FrameLoadType type, |
1445 NavigationPolicy navigation_policy, | 1488 NavigationPolicy navigation_policy, |
1446 NavigationType navigation_type) { | 1489 NavigationType navigation_type) { |
1447 if (frame_->GetDocument()->PageDismissalEventBeingDispatched() != | 1490 if (frame_->GetDocument()->PageDismissalEventBeingDispatched() != |
1448 Document::kNoDismissal) { | 1491 Document::kNoDismissal) { |
1449 return kNavigationPolicyIgnore; | 1492 return kNavigationPolicyIgnore; |
1450 } | 1493 } |
1451 | 1494 |
1452 // Record the latest requiredCSP value that will be used when sending this | 1495 // Record the latest requiredCSP value that will be used when sending this |
1453 // request. | 1496 // request. |
1454 ResourceRequest& resource_request = frame_load_request.GetResourceRequest(); | 1497 ResourceRequest& resource_request = frame_load_request.GetResourceRequest(); |
1455 RecordLatestRequiredCSP(); | 1498 RecordLatestRequiredCSP(); |
1499 // Before modifying the request, check report-only CSP headers to give the | |
1500 // site owner a chance to learn about requests that need to be modified. | |
1501 // | |
1502 // TODO(estark): this doesn't work with --enable-browser-side-navigation, | |
1503 // wherein 'frame-src' is checked in the browser process. Figure out what to | |
1504 // do; maybe with browser-side navigation the upgrade should be happening in | |
1505 // the browser process too. See also https://crbug.com/692595 | |
Mike West
2017/04/19 08:42:13
Ugh. Yes. This is a mess.
Given infinite time, we
| |
1506 Settings* settings = frame_->GetSettings(); | |
1507 MaybeCheckCSP( | |
1508 resource_request, navigation_type, frame_, navigation_policy, | |
1509 frame_load_request.ShouldCheckMainWorldContentSecurityPolicy() == | |
1510 kCheckContentSecurityPolicy, | |
1511 settings && settings->GetBrowserSideNavigationEnabled(), | |
1512 ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly); | |
1456 ModifyRequestForCSP(resource_request, nullptr); | 1513 ModifyRequestForCSP(resource_request, nullptr); |
1457 | 1514 |
1458 return ShouldContinueForNavigationPolicy( | 1515 return ShouldContinueForNavigationPolicy( |
1459 resource_request, frame_load_request.GetSubstituteData(), nullptr, | 1516 resource_request, frame_load_request.GetSubstituteData(), nullptr, |
1460 frame_load_request.ShouldCheckMainWorldContentSecurityPolicy(), | 1517 frame_load_request.ShouldCheckMainWorldContentSecurityPolicy(), |
1461 navigation_type, navigation_policy, type, | 1518 navigation_type, navigation_policy, type, |
1462 frame_load_request.ClientRedirect() == | 1519 frame_load_request.ClientRedirect() == |
1463 ClientRedirectPolicy::kClientRedirect, | 1520 ClientRedirectPolicy::kClientRedirect, |
1464 frame_load_request.Form()); | 1521 frame_load_request.Form()); |
1465 } | 1522 } |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1774 // TODO(japhet): This is needed because the browser process DCHECKs if the | 1831 // TODO(japhet): This is needed because the browser process DCHECKs if the |
1775 // first entry we commit in a new frame has replacement set. It's unclear | 1832 // first entry we commit in a new frame has replacement set. It's unclear |
1776 // whether the DCHECK is right, investigate removing this special case. | 1833 // whether the DCHECK is right, investigate removing this special case. |
1777 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem && | 1834 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem && |
1778 (!Opener() || !request.Url().IsEmpty()); | 1835 (!Opener() || !request.Url().IsEmpty()); |
1779 loader->SetReplacesCurrentHistoryItem(replace_current_item); | 1836 loader->SetReplacesCurrentHistoryItem(replace_current_item); |
1780 return loader; | 1837 return loader; |
1781 } | 1838 } |
1782 | 1839 |
1783 } // namespace blink | 1840 } // namespace blink |
OLD | NEW |