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

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: Addressed comments (@alexmos #2) 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 m_substituteData(substituteData), 105 m_substituteData(substituteData),
106 m_request(req), 106 m_request(req),
107 m_isClientRedirect(clientRedirectPolicy == 107 m_isClientRedirect(clientRedirectPolicy ==
108 ClientRedirectPolicy::ClientRedirect), 108 ClientRedirectPolicy::ClientRedirect),
109 m_replacesCurrentHistoryItem(false), 109 m_replacesCurrentHistoryItem(false),
110 m_dataReceived(false), 110 m_dataReceived(false),
111 m_navigationType(NavigationTypeOther), 111 m_navigationType(NavigationTypeOther),
112 m_documentLoadTiming(*this), 112 m_documentLoadTiming(*this),
113 m_timeOfLastDataReceived(0.0), 113 m_timeOfLastDataReceived(0.0),
114 m_applicationCacheHost(ApplicationCacheHost::create(this)), 114 m_applicationCacheHost(ApplicationCacheHost::create(this)),
115 m_wasBlockedAfterXFrameOptionsOrCSP(false), 115 m_wasBlockedAfterCSP(false),
116 m_state(NotStarted), 116 m_state(NotStarted),
117 m_inDataReceived(false), 117 m_inDataReceived(false),
118 m_dataBuffer(SharedBuffer::create()) { 118 m_dataBuffer(SharedBuffer::create()) {
119 // The document URL needs to be added to the head of the list as that is 119 // The document URL needs to be added to the head of the list as that is
120 // where the redirects originated. 120 // where the redirects originated.
121 if (m_isClientRedirect) 121 if (m_isClientRedirect)
122 appendRedirect(m_frame->document()->url()); 122 appendRedirect(m_frame->document()->url());
123 } 123 }
124 124
125 FrameLoader* DocumentLoader::frameLoader() const { 125 FrameLoader* DocumentLoader::frameLoader() const {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 DCHECK(m_mainResource); 279 DCHECK(m_mainResource);
280 280
281 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) { 281 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) {
282 finishedLoading(m_mainResource->loadFinishTime()); 282 finishedLoading(m_mainResource->loadFinishTime());
283 return; 283 return;
284 } 284 }
285 285
286 if (m_applicationCacheHost) 286 if (m_applicationCacheHost)
287 m_applicationCacheHost->failedLoadingMainResource(); 287 m_applicationCacheHost->failedLoadingMainResource();
288 m_state = MainResourceDone; 288 m_state = MainResourceDone;
289
290 if (m_mainResource->resourceError().wasBlockedByResponse()) {
291 InspectorInstrumentation::canceledAfterReceivedResourceResponse(
292 m_frame, this, mainResourceIdentifier(), resource->response(),
293 m_mainResource.get());
294 }
295
289 frameLoader()->loadFailed(this, m_mainResource->resourceError()); 296 frameLoader()->loadFailed(this, m_mainResource->resourceError());
290 clearMainResourceHandle(); 297 clearMainResourceHandle();
291 } 298 }
292 299
293 void DocumentLoader::finishedLoading(double finishTime) { 300 void DocumentLoader::finishedLoading(double finishTime) {
294 DCHECK(m_frame->loader().stateMachine()->creatingInitialEmptyDocument() || 301 DCHECK(m_frame->loader().stateMachine()->creatingInitialEmptyDocument() ||
295 !m_frame->page()->suspended() || 302 !m_frame->page()->suspended() ||
296 InspectorInstrumentation::isDebuggerPaused(m_frame)); 303 InspectorInstrumentation::isDebuggerPaused(m_frame));
297 304
298 double responseEndTime = finishTime; 305 double responseEndTime = finishTime;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 // Downloading is handled by the embedder, but we still get the initial 402 // Downloading is handled by the embedder, but we still get the initial
396 // response so that we can ignore it and clean up properly. 403 // response so that we can ignore it and clean up properly.
397 return false; 404 return false;
398 } 405 }
399 406
400 if (!canShowMIMEType(m_response.mimeType(), m_frame)) 407 if (!canShowMIMEType(m_response.mimeType(), m_frame))
401 return false; 408 return false;
402 return true; 409 return true;
403 } 410 }
404 411
405 void DocumentLoader::cancelLoadAfterXFrameOptionsOrCSPDenied( 412 void DocumentLoader::cancelLoadAfterCSPDenied(
406 const ResourceResponse& response) { 413 const ResourceResponse& response) {
407 InspectorInstrumentation::continueAfterXFrameOptionsDenied( 414 InspectorInstrumentation::canceledAfterReceivedResourceResponse(
408 m_frame, this, mainResourceIdentifier(), response, m_mainResource.get()); 415 m_frame, this, mainResourceIdentifier(), response, m_mainResource.get());
409 416
410 setWasBlockedAfterXFrameOptionsOrCSP(); 417 setWasBlockedAfterCSP();
411 418
412 // Pretend that this was an empty HTTP 200 response. Don't reuse the original 419 // Pretend that this was an empty HTTP 200 response. Don't reuse the original
413 // URL for the empty page (https://crbug.com/622385). 420 // URL for the empty page (https://crbug.com/622385).
414 // 421 //
415 // TODO(mkwst): Remove this once XFO moves to the browser. 422 // TODO(mkwst): Remove this once XFO moves to the browser.
416 // https://crbug.com/555418. 423 // https://crbug.com/555418.
417 clearMainResourceHandle(); 424 clearMainResourceHandle();
418 m_contentSecurityPolicy.clear(); 425 m_contentSecurityPolicy.clear();
419 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin(); 426 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin();
420 m_originalRequest.setURL(blockedURL); 427 m_originalRequest.setURL(blockedURL);
(...skipping 21 matching lines...) Expand all
442 // we don't save the result for future use. All responses loaded from appcache 449 // we don't save the result for future use. All responses loaded from appcache
443 // will have a non-zero appCacheID(). 450 // will have a non-zero appCacheID().
444 if (response.appCacheID()) 451 if (response.appCacheID())
445 memoryCache()->remove(m_mainResource.get()); 452 memoryCache()->remove(m_mainResource.get());
446 453
447 m_contentSecurityPolicy = ContentSecurityPolicy::create(); 454 m_contentSecurityPolicy = ContentSecurityPolicy::create();
448 m_contentSecurityPolicy->setOverrideURLForSelf(response.url()); 455 m_contentSecurityPolicy->setOverrideURLForSelf(response.url());
449 m_contentSecurityPolicy->didReceiveHeaders( 456 m_contentSecurityPolicy->didReceiveHeaders(
450 ContentSecurityPolicyResponseHeaders(response)); 457 ContentSecurityPolicyResponseHeaders(response));
451 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) { 458 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) {
452 cancelLoadAfterXFrameOptionsOrCSPDenied(response); 459 cancelLoadAfterCSPDenied(response);
453 return; 460 return;
454 } 461 }
455 462
456 // 'frame-ancestors' obviates 'x-frame-options':
457 // https://w3c.github.io/webappsec/specs/content-security-policy/#frame-ancest ors-and-frame-options
458 if (!m_contentSecurityPolicy->isFrameAncestorsEnforced()) {
459 HTTPHeaderMap::const_iterator it =
460 response.httpHeaderFields().find(HTTPNames::X_Frame_Options);
461 if (it != response.httpHeaderFields().end()) {
462 String content = it->value;
463 if (frameLoader()->shouldInterruptLoadForXFrameOptions(
464 content, response.url(), mainResourceIdentifier())) {
465 String message = "Refused to display '" +
466 response.url().elidedString() +
467 "' in a frame because it set 'X-Frame-Options' to '" +
468 content + "'.";
469 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest(
470 SecurityMessageSource, ErrorMessageLevel, message, response.url(),
471 mainResourceIdentifier());
472 frame()->document()->addConsoleMessage(consoleMessage);
473
474 cancelLoadAfterXFrameOptionsOrCSPDenied(response);
475 return;
476 }
477 }
478 }
479
480 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() && 463 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() &&
481 !frameLoader()->requiredCSP().isEmpty()) { 464 !frameLoader()->requiredCSP().isEmpty()) {
482 SecurityOrigin* parentSecurityOrigin = 465 SecurityOrigin* parentSecurityOrigin =
483 frame()->tree().parent()->securityContext()->getSecurityOrigin(); 466 frame()->tree().parent()->securityContext()->getSecurityOrigin();
484 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy( 467 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy(
485 response, parentSecurityOrigin)) { 468 response, parentSecurityOrigin)) {
486 m_contentSecurityPolicy->addPolicyFromHeaderValue( 469 m_contentSecurityPolicy->addPolicyFromHeaderValue(
487 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, 470 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce,
488 ContentSecurityPolicyHeaderSourceHTTP); 471 ContentSecurityPolicyHeaderSourceHTTP);
489 } else { 472 } else {
490 ContentSecurityPolicy* embeddingCSP = ContentSecurityPolicy::create(); 473 ContentSecurityPolicy* embeddingCSP = ContentSecurityPolicy::create();
491 embeddingCSP->addPolicyFromHeaderValue( 474 embeddingCSP->addPolicyFromHeaderValue(
492 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, 475 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce,
493 ContentSecurityPolicyHeaderSourceHTTP); 476 ContentSecurityPolicyHeaderSourceHTTP);
494 if (!embeddingCSP->subsumes(*m_contentSecurityPolicy)) { 477 if (!embeddingCSP->subsumes(*m_contentSecurityPolicy)) {
495 String message = "Refused to display '" + 478 String message = "Refused to display '" +
496 response.url().elidedString() + 479 response.url().elidedString() +
497 "' because it has not opted-into the following policy " 480 "' because it has not opted-into the following policy "
498 "required by its embedder: '" + 481 "required by its embedder: '" +
499 frameLoader()->requiredCSP() + "'."; 482 frameLoader()->requiredCSP() + "'.";
500 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest( 483 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest(
501 SecurityMessageSource, ErrorMessageLevel, message, response.url(), 484 SecurityMessageSource, ErrorMessageLevel, message, response.url(),
502 mainResourceIdentifier()); 485 mainResourceIdentifier());
503 frame()->document()->addConsoleMessage(consoleMessage); 486 frame()->document()->addConsoleMessage(consoleMessage);
504 cancelLoadAfterXFrameOptionsOrCSPDenied(response); 487 cancelLoadAfterCSPDenied(response);
505 return; 488 return;
506 } 489 }
507 } 490 }
508 } 491 }
509 492
510 DCHECK(!m_frame->page()->suspended()); 493 DCHECK(!m_frame->page()->suspended());
511 494
512 m_response = response; 495 m_response = response;
513 496
514 if (isArchiveMIMEType(m_response.mimeType()) && 497 if (isArchiveMIMEType(m_response.mimeType()) &&
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 m_writer ? m_writer->encoding() : emptyAtom, true, 800 m_writer ? m_writer->encoding() : emptyAtom, true,
818 ForceSynchronousParsing); 801 ForceSynchronousParsing);
819 if (!source.isNull()) 802 if (!source.isNull())
820 m_writer->appendReplacingData(source); 803 m_writer->appendReplacingData(source);
821 endWriting(); 804 endWriting();
822 } 805 }
823 806
824 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); 807 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader);
825 808
826 } // namespace blink 809 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698