Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Side by Side Diff: third_party/WebKit/Source/core/loader/DocumentLoader.cpp

Issue 2488743003: (Re-)introduce AncestorThrottle to handle 'X-Frame-Options'. (Closed)
Patch Set: Display a blank page instead of an error page. ( and add checks in NavigationRequest) Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 m_substituteData(substituteData), 104 m_substituteData(substituteData),
105 m_request(req), 105 m_request(req),
106 m_isClientRedirect(clientRedirectPolicy == 106 m_isClientRedirect(clientRedirectPolicy ==
107 ClientRedirectPolicy::ClientRedirect), 107 ClientRedirectPolicy::ClientRedirect),
108 m_replacesCurrentHistoryItem(false), 108 m_replacesCurrentHistoryItem(false),
109 m_dataReceived(false), 109 m_dataReceived(false),
110 m_navigationType(NavigationTypeOther), 110 m_navigationType(NavigationTypeOther),
111 m_documentLoadTiming(*this), 111 m_documentLoadTiming(*this),
112 m_timeOfLastDataReceived(0.0), 112 m_timeOfLastDataReceived(0.0),
113 m_applicationCacheHost(ApplicationCacheHost::create(this)), 113 m_applicationCacheHost(ApplicationCacheHost::create(this)),
114 m_wasBlockedAfterXFrameOptionsOrCSP(false), 114 m_wasBlockedAfterCSP(false),
115 m_state(NotStarted), 115 m_state(NotStarted),
116 m_inDataReceived(false), 116 m_inDataReceived(false),
117 m_dataBuffer(SharedBuffer::create()) { 117 m_dataBuffer(SharedBuffer::create()) {
118 // The document URL needs to be added to the head of the list as that is 118 // The document URL needs to be added to the head of the list as that is
119 // where the redirects originated. 119 // where the redirects originated.
120 if (m_isClientRedirect) 120 if (m_isClientRedirect)
121 appendRedirect(m_frame->document()->url()); 121 appendRedirect(m_frame->document()->url());
122 } 122 }
123 123
124 FrameLoader* DocumentLoader::frameLoader() const { 124 FrameLoader* DocumentLoader::frameLoader() const {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 DCHECK(m_mainResource); 274 DCHECK(m_mainResource);
275 275
276 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) { 276 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) {
277 finishedLoading(m_mainResource->loadFinishTime()); 277 finishedLoading(m_mainResource->loadFinishTime());
278 return; 278 return;
279 } 279 }
280 280
281 if (m_applicationCacheHost) 281 if (m_applicationCacheHost)
282 m_applicationCacheHost->failedLoadingMainResource(); 282 m_applicationCacheHost->failedLoadingMainResource();
283 m_state = MainResourceDone; 283 m_state = MainResourceDone;
284
285 if (m_mainResource->resourceError().wasBlockedByResponse()) {
286 InspectorInstrumentation::canceledAfterReceivedResourceResponse(
287 m_frame, this, mainResourceIdentifier(), resource->response(),
288 m_mainResource.get());
289 }
290
284 frameLoader()->loadFailed(this, m_mainResource->resourceError()); 291 frameLoader()->loadFailed(this, m_mainResource->resourceError());
285 clearMainResourceHandle(); 292 clearMainResourceHandle();
286 } 293 }
287 294
288 void DocumentLoader::finishedLoading(double finishTime) { 295 void DocumentLoader::finishedLoading(double finishTime) {
289 DCHECK(m_frame->loader().stateMachine()->creatingInitialEmptyDocument() || 296 DCHECK(m_frame->loader().stateMachine()->creatingInitialEmptyDocument() ||
290 !m_frame->page()->defersLoading() || 297 !m_frame->page()->defersLoading() ||
291 InspectorInstrumentation::isDebuggerPaused(m_frame)); 298 InspectorInstrumentation::isDebuggerPaused(m_frame));
292 299
293 double responseEndTime = finishTime; 300 double responseEndTime = finishTime;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 // Downloading is handled by the embedder, but we still get the initial 384 // Downloading is handled by the embedder, but we still get the initial
378 // response so that we can ignore it and clean up properly. 385 // response so that we can ignore it and clean up properly.
379 return false; 386 return false;
380 } 387 }
381 388
382 if (!canShowMIMEType(m_response.mimeType(), m_frame)) 389 if (!canShowMIMEType(m_response.mimeType(), m_frame))
383 return false; 390 return false;
384 return true; 391 return true;
385 } 392 }
386 393
387 void DocumentLoader::cancelLoadAfterXFrameOptionsOrCSPDenied( 394 void DocumentLoader::cancelLoadAfterCSPDenied(
388 const ResourceResponse& response) { 395 const ResourceResponse& response) {
389 InspectorInstrumentation::continueAfterXFrameOptionsDenied( 396 InspectorInstrumentation::canceledAfterReceivedResourceResponse(
390 m_frame, this, mainResourceIdentifier(), response, m_mainResource.get()); 397 m_frame, this, mainResourceIdentifier(), response, m_mainResource.get());
391 398
392 setWasBlockedAfterXFrameOptionsOrCSP(); 399 setWasBlockedAfterCSP();
393 400
394 // Pretend that this was an empty HTTP 200 response. Don't reuse the original 401 // Pretend that this was an empty HTTP 200 response. Don't reuse the original
395 // URL for the empty page (https://crbug.com/622385). 402 // URL for the empty page (https://crbug.com/622385).
396 // 403 //
397 // TODO(mkwst): Remove this once XFO moves to the browser. 404 // TODO(mkwst): Remove this once XFO moves to the browser.
398 // https://crbug.com/555418. 405 // https://crbug.com/555418.
399 clearMainResourceHandle(); 406 clearMainResourceHandle();
400 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin(); 407 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin();
401 m_originalRequest.setURL(blockedURL); 408 m_originalRequest.setURL(blockedURL);
402 m_request.setURL(blockedURL); 409 m_request.setURL(blockedURL);
(...skipping 20 matching lines...) Expand all
423 // we don't save the result for future use. All responses loaded from appcache 430 // we don't save the result for future use. All responses loaded from appcache
424 // will have a non-zero appCacheID(). 431 // will have a non-zero appCacheID().
425 if (response.appCacheID()) 432 if (response.appCacheID())
426 memoryCache()->remove(m_mainResource.get()); 433 memoryCache()->remove(m_mainResource.get());
427 434
428 m_contentSecurityPolicy = ContentSecurityPolicy::create(); 435 m_contentSecurityPolicy = ContentSecurityPolicy::create();
429 m_contentSecurityPolicy->setOverrideURLForSelf(response.url()); 436 m_contentSecurityPolicy->setOverrideURLForSelf(response.url());
430 m_contentSecurityPolicy->didReceiveHeaders( 437 m_contentSecurityPolicy->didReceiveHeaders(
431 ContentSecurityPolicyResponseHeaders(response)); 438 ContentSecurityPolicyResponseHeaders(response));
432 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) { 439 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) {
433 cancelLoadAfterXFrameOptionsOrCSPDenied(response); 440 cancelLoadAfterCSPDenied(response);
434 return; 441 return;
435 } 442 }
436 443
437 // 'frame-ancestors' obviates 'x-frame-options':
438 // https://w3c.github.io/webappsec/specs/content-security-policy/#frame-ancest ors-and-frame-options
439 if (!m_contentSecurityPolicy->isFrameAncestorsEnforced()) {
440 HTTPHeaderMap::const_iterator it =
441 response.httpHeaderFields().find(HTTPNames::X_Frame_Options);
442 if (it != response.httpHeaderFields().end()) {
443 String content = it->value;
444 if (frameLoader()->shouldInterruptLoadForXFrameOptions(
445 content, response.url(), mainResourceIdentifier())) {
446 String message = "Refused to display '" +
447 response.url().elidedString() +
448 "' in a frame because it set 'X-Frame-Options' to '" +
449 content + "'.";
450 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest(
451 SecurityMessageSource, ErrorMessageLevel, message, response.url(),
452 mainResourceIdentifier());
453 frame()->document()->addConsoleMessage(consoleMessage);
454
455 cancelLoadAfterXFrameOptionsOrCSPDenied(response);
456 return;
457 }
458 }
459 }
460
461 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() && 444 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() &&
462 !frameLoader()->requiredCSP().isEmpty()) { 445 !frameLoader()->requiredCSP().isEmpty()) {
463 SecurityOrigin* parentSecurityOrigin = 446 SecurityOrigin* parentSecurityOrigin =
464 frame()->tree().parent()->securityContext()->getSecurityOrigin(); 447 frame()->tree().parent()->securityContext()->getSecurityOrigin();
465 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy( 448 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy(
466 response, parentSecurityOrigin)) { 449 response, parentSecurityOrigin)) {
467 m_contentSecurityPolicy->addPolicyFromHeaderValue( 450 m_contentSecurityPolicy->addPolicyFromHeaderValue(
468 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, 451 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce,
469 ContentSecurityPolicyHeaderSourceHTTP); 452 ContentSecurityPolicyHeaderSourceHTTP);
470 } else { 453 } else {
471 String message = "Refused to display '" + response.url().elidedString() + 454 String message = "Refused to display '" + response.url().elidedString() +
472 "' because it has not opted-into the following policy " 455 "' because it has not opted-into the following policy "
473 "required by its embedder: '" + 456 "required by its embedder: '" +
474 frameLoader()->requiredCSP() + "'."; 457 frameLoader()->requiredCSP() + "'.";
475 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest( 458 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest(
476 SecurityMessageSource, ErrorMessageLevel, message, response.url(), 459 SecurityMessageSource, ErrorMessageLevel, message, response.url(),
477 mainResourceIdentifier()); 460 mainResourceIdentifier());
478 frame()->document()->addConsoleMessage(consoleMessage); 461 frame()->document()->addConsoleMessage(consoleMessage);
479 cancelLoadAfterXFrameOptionsOrCSPDenied(response); 462 cancelLoadAfterCSPDenied(response);
480 return; 463 return;
481 } 464 }
482 } 465 }
483 466
484 DCHECK(!m_frame->page()->defersLoading()); 467 DCHECK(!m_frame->page()->defersLoading());
485 468
486 m_response = response; 469 m_response = response;
487 470
488 if (isArchiveMIMEType(m_response.mimeType()) && 471 if (isArchiveMIMEType(m_response.mimeType()) &&
489 m_mainResource->getDataBufferingPolicy() != BufferData) 472 m_mainResource->getDataBufferingPolicy() != BufferData)
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 m_writer ? m_writer->encoding() : emptyAtom, true, 776 m_writer ? m_writer->encoding() : emptyAtom, true,
794 ForceSynchronousParsing); 777 ForceSynchronousParsing);
795 if (!source.isNull()) 778 if (!source.isNull())
796 m_writer->appendReplacingData(source); 779 m_writer->appendReplacingData(source);
797 endWriting(); 780 endWriting();
798 } 781 }
799 782
800 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); 783 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader);
801 784
802 } // namespace blink 785 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698