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

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 (@clamy). 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()->suspended() || 297 !m_frame->page()->suspended() ||
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 m_contentSecurityPolicy.clear(); 407 m_contentSecurityPolicy.clear();
401 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin(); 408 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin();
402 m_originalRequest.setURL(blockedURL); 409 m_originalRequest.setURL(blockedURL);
(...skipping 21 matching lines...) Expand all
424 // we don't save the result for future use. All responses loaded from appcache 431 // we don't save the result for future use. All responses loaded from appcache
425 // will have a non-zero appCacheID(). 432 // will have a non-zero appCacheID().
426 if (response.appCacheID()) 433 if (response.appCacheID())
427 memoryCache()->remove(m_mainResource.get()); 434 memoryCache()->remove(m_mainResource.get());
428 435
429 m_contentSecurityPolicy = ContentSecurityPolicy::create(); 436 m_contentSecurityPolicy = ContentSecurityPolicy::create();
430 m_contentSecurityPolicy->setOverrideURLForSelf(response.url()); 437 m_contentSecurityPolicy->setOverrideURLForSelf(response.url());
431 m_contentSecurityPolicy->didReceiveHeaders( 438 m_contentSecurityPolicy->didReceiveHeaders(
432 ContentSecurityPolicyResponseHeaders(response)); 439 ContentSecurityPolicyResponseHeaders(response));
433 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) { 440 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) {
434 cancelLoadAfterXFrameOptionsOrCSPDenied(response); 441 cancelLoadAfterCSPDenied(response);
435 return; 442 return;
436 } 443 }
437 444
438 // 'frame-ancestors' obviates 'x-frame-options':
439 // https://w3c.github.io/webappsec/specs/content-security-policy/#frame-ancest ors-and-frame-options
440 if (!m_contentSecurityPolicy->isFrameAncestorsEnforced()) {
441 HTTPHeaderMap::const_iterator it =
442 response.httpHeaderFields().find(HTTPNames::X_Frame_Options);
443 if (it != response.httpHeaderFields().end()) {
444 String content = it->value;
445 if (frameLoader()->shouldInterruptLoadForXFrameOptions(
446 content, response.url(), mainResourceIdentifier())) {
447 String message = "Refused to display '" +
448 response.url().elidedString() +
449 "' in a frame because it set 'X-Frame-Options' to '" +
450 content + "'.";
451 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest(
452 SecurityMessageSource, ErrorMessageLevel, message, response.url(),
453 mainResourceIdentifier());
454 frame()->document()->addConsoleMessage(consoleMessage);
455
456 cancelLoadAfterXFrameOptionsOrCSPDenied(response);
457 return;
458 }
459 }
460 }
461
462 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() && 445 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() &&
463 !frameLoader()->requiredCSP().isEmpty()) { 446 !frameLoader()->requiredCSP().isEmpty()) {
464 SecurityOrigin* parentSecurityOrigin = 447 SecurityOrigin* parentSecurityOrigin =
465 frame()->tree().parent()->securityContext()->getSecurityOrigin(); 448 frame()->tree().parent()->securityContext()->getSecurityOrigin();
466 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy( 449 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy(
467 response, parentSecurityOrigin)) { 450 response, parentSecurityOrigin)) {
468 m_contentSecurityPolicy->addPolicyFromHeaderValue( 451 m_contentSecurityPolicy->addPolicyFromHeaderValue(
469 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, 452 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce,
470 ContentSecurityPolicyHeaderSourceHTTP); 453 ContentSecurityPolicyHeaderSourceHTTP);
471 } else { 454 } else {
472 ContentSecurityPolicy* embeddingCSP = ContentSecurityPolicy::create(); 455 ContentSecurityPolicy* embeddingCSP = ContentSecurityPolicy::create();
473 embeddingCSP->addPolicyFromHeaderValue( 456 embeddingCSP->addPolicyFromHeaderValue(
474 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, 457 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce,
475 ContentSecurityPolicyHeaderSourceHTTP); 458 ContentSecurityPolicyHeaderSourceHTTP);
476 if (!embeddingCSP->subsumes(*m_contentSecurityPolicy)) { 459 if (!embeddingCSP->subsumes(*m_contentSecurityPolicy)) {
477 String message = "Refused to display '" + 460 String message = "Refused to display '" +
478 response.url().elidedString() + 461 response.url().elidedString() +
479 "' because it has not opted-into the following policy " 462 "' because it has not opted-into the following policy "
480 "required by its embedder: '" + 463 "required by its embedder: '" +
481 frameLoader()->requiredCSP() + "'."; 464 frameLoader()->requiredCSP() + "'.";
482 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest( 465 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest(
483 SecurityMessageSource, ErrorMessageLevel, message, response.url(), 466 SecurityMessageSource, ErrorMessageLevel, message, response.url(),
484 mainResourceIdentifier()); 467 mainResourceIdentifier());
485 frame()->document()->addConsoleMessage(consoleMessage); 468 frame()->document()->addConsoleMessage(consoleMessage);
486 cancelLoadAfterXFrameOptionsOrCSPDenied(response); 469 cancelLoadAfterCSPDenied(response);
487 return; 470 return;
488 } 471 }
489 } 472 }
490 } 473 }
491 474
492 DCHECK(!m_frame->page()->suspended()); 475 DCHECK(!m_frame->page()->suspended());
493 476
494 m_response = response; 477 m_response = response;
495 478
496 if (isArchiveMIMEType(m_response.mimeType()) && 479 if (isArchiveMIMEType(m_response.mimeType()) &&
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 m_writer ? m_writer->encoding() : emptyAtom, true, 784 m_writer ? m_writer->encoding() : emptyAtom, true,
802 ForceSynchronousParsing); 785 ForceSynchronousParsing);
803 if (!source.isNull()) 786 if (!source.isNull())
804 m_writer->appendReplacingData(source); 787 m_writer->appendReplacingData(source);
805 endWriting(); 788 endWriting();
806 } 789 }
807 790
808 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); 791 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader);
809 792
810 } // namespace blink 793 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698