#### VULNERABILITY DETAILS This is a regression from https://crrev.com/f92a1f3b9 . Previously, ResourceLoader::start bailed out if ResourceLoader::m_defersLoading was true. Now, it calls setDefersLoading on the associated WebURLLoader instead: ``` void ResourceLoader::start(ResourceRequest& request) { (...) m_loader = adoptPtr(Platform::current()->createURLLoader()); m_loader->setDefersLoading(m_fetcher->defersLoading()); ASSERT(m_loader); m_loader->setLoadingTaskRunner(m_fetcher->loadingTaskRunner()); if (m_resource->options().synchronousPolicy == RequestSynchronously) requestSynchronously(request); else m_loader->loadAsynchronously(WrappedResourceRequest(request), this); } void WebURLLoaderImpl::setDefersLoading(bool value) { context_->SetDefersLoading(value); } void WebURLLoaderImpl::Context::SetDefersLoading(bool value) { if (request_id_ != -1) resource_dispatcher_->SetDefersLoading(request_id_, value); (...) } ``` Note that |resource_dispatcher_->SetDefersLoading(request_id_,...
#### VULNERABILITY DETAILS This is a regression from https://crrev.com/f92a1f3b9 . Previously, ResourceLoader::start bailed out if ResourceLoader::m_defersLoading was true. Now, it calls setDefersLoading on the associated WebURLLoader instead: ``` void ResourceLoader::start(ResourceRequest& request) { (...) m_loader = adoptPtr(Platform::current()->createURLLoader()); m_loader->setDefersLoading(m_fetcher->defersLoading()); ASSERT(m_loader); m_loader->setLoadingTaskRunner(m_fetcher->loadingTaskRunner()); if (m_resource->options().synchronousPolicy == RequestSynchronously) requestSynchronously(request); else m_loader->loadAsynchronously(WrappedResourceRequest(request), this); } void WebURLLoaderImpl::setDefersLoading(bool value) { context_->SetDefersLoading(value); } void WebURLLoaderImpl::Context::SetDefersLoading(bool value) { if (request_id_ != -1) resource_dispatcher_->SetDefersLoading(request_id_, value); (...) } ``` Note that |resource_dispatcher_->SetDefersLoading(request_id_, value)| isn't called because |request_id_| isn't set until after the |m_loader->loadAsynchronously| call in ResourceLoader::start. Therefore, if a load is started after instantiating a ScopedPageLoadDeferrer, the pending request is never marked as deferred and it's allowed to proceed regardless of the deferral state of the fetcher. This allows an attacker to load cross-origin documents in numerous unexpected circumstances. #### VERSION Chrome 51.0.2700.0 (Dev) Chromium 51.0.2703.0 + Pepper Flash (Release build compiled today) 附件:[load-deferral-logic.zip](http://paper.seebug.org/papers/Archive/poc/load-deferral-logic.zip)