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

Side by Side Diff: Source/core/loader/cache/CachedResourceLoader.cpp

Issue 14949017: Implementation of W3C compliant CSP script-src nonce. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fixed broken nonce behavior on script redirects. Added test for redirects as well. Created 7 years, 7 months 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) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ 6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
7 7
8 This library is free software; you can redistribute it and/or 8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public 9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either 10 License as published by the Free Software Foundation; either
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 Frame* CachedResourceLoader::frame() const 139 Frame* CachedResourceLoader::frame() const
140 { 140 {
141 return m_documentLoader ? m_documentLoader->frame() : 0; 141 return m_documentLoader ? m_documentLoader->frame() : 0;
142 } 142 }
143 143
144 CachedResourceHandle<CachedImage> CachedResourceLoader::requestImage(CachedResou rceRequest& request) 144 CachedResourceHandle<CachedImage> CachedResourceLoader::requestImage(CachedResou rceRequest& request)
145 { 145 {
146 if (Frame* f = frame()) { 146 if (Frame* f = frame()) {
147 if (f->loader()->pageDismissalEventBeingDispatched() != FrameLoader::NoD ismissal) { 147 if (f->loader()->pageDismissalEventBeingDispatched() != FrameLoader::NoD ismissal) {
148 KURL requestURL = request.resourceRequest().url(); 148 KURL requestURL = request.resourceRequest().url();
149 if (requestURL.isValid() && canRequest(CachedResource::ImageResource , requestURL)) 149 if (requestURL.isValid() && canRequest(CachedResource::ImageResource , requestURL, false))
abarth-chromium 2013/05/16 00:59:27 If you use the enum rather than a bool, then call
jww 2013/05/16 20:59:00 Done.
150 PingLoader::loadImage(f, requestURL); 150 PingLoader::loadImage(f, requestURL);
151 return 0; 151 return 0;
152 } 152 }
153 } 153 }
154 request.setDefer(clientDefersImage(request.resourceRequest().url()) ? Cached ResourceRequest::DeferredByClient : CachedResourceRequest::NoDefer); 154 request.setDefer(clientDefersImage(request.resourceRequest().url()) ? Cached ResourceRequest::DeferredByClient : CachedResourceRequest::NoDefer);
155 return static_cast<CachedImage*>(requestResource(CachedResource::ImageResour ce, request).get()); 155 return static_cast<CachedImage*>(requestResource(CachedResource::ImageResour ce, request).get());
156 } 156 }
157 157
158 CachedResourceHandle<CachedFont> CachedResourceLoader::requestFont(CachedResourc eRequest& request) 158 CachedResourceHandle<CachedFont> CachedResourceLoader::requestFont(CachedResourc eRequest& request)
159 { 159 {
(...skipping 25 matching lines...) Expand all
185 memoryCache()->remove(existing); 185 memoryCache()->remove(existing);
186 } 186 }
187 if (url.string() != request.resourceRequest().url()) 187 if (url.string() != request.resourceRequest().url())
188 request.mutableResourceRequest().setURL(url); 188 request.mutableResourceRequest().setURL(url);
189 189
190 CachedResourceHandle<CachedCSSStyleSheet> userSheet = new CachedCSSStyleShee t(request.resourceRequest(), request.charset()); 190 CachedResourceHandle<CachedCSSStyleSheet> userSheet = new CachedCSSStyleShee t(request.resourceRequest(), request.charset());
191 191
192 memoryCache()->add(userSheet.get()); 192 memoryCache()->add(userSheet.get());
193 // FIXME: loadResource calls setOwningCachedResourceLoader() if the resource couldn't be added to cache. Does this function need to call it, too? 193 // FIXME: loadResource calls setOwningCachedResourceLoader() if the resource couldn't be added to cache. Does this function need to call it, too?
194 194
195 userSheet->load(this, ResourceLoaderOptions(DoNotSendCallbacks, SniffContent , BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSe curityCheck)); 195 // This check is currently not used. However, it will be used once we
196 // implement nonce checks for style sheets.
197 ContentSecurityPolicyNonceCheck nonceCheck = NonceCheckNotValid;
198 if (checkNonceFromInitiatorElement(request.initiatorElement().get()))
199 nonceCheck = NonceCheckValid;
abarth-chromium 2013/05/16 00:59:27 If this code isn't used, we shouldn't add it. We
jww 2013/05/16 20:59:00 Done.
200 userSheet->load(this, ResourceLoaderOptions(DoNotSendCallbacks, SniffContent , BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSe curityCheck, nonceCheck));
196 201
197 return userSheet; 202 return userSheet;
198 } 203 }
199 204
200 CachedResourceHandle<CachedScript> CachedResourceLoader::requestScript(CachedRes ourceRequest& request) 205 CachedResourceHandle<CachedScript> CachedResourceLoader::requestScript(CachedRes ourceRequest& request)
201 { 206 {
202 return static_cast<CachedScript*>(requestResource(CachedResource::Script, re quest).get()); 207 return static_cast<CachedScript*>(requestResource(CachedResource::Script, re quest).get());
203 } 208 }
204 209
205 CachedResourceHandle<CachedXSLStyleSheet> CachedResourceLoader::requestXSLStyleS heet(CachedResourceRequest& request) 210 CachedResourceHandle<CachedXSLStyleSheet> CachedResourceLoader::requestXSLStyleS heet(CachedResourceRequest& request)
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 } 266 }
262 case CachedResource::MainResource: 267 case CachedResource::MainResource:
263 case CachedResource::LinkPrefetch: 268 case CachedResource::LinkPrefetch:
264 case CachedResource::LinkSubresource: 269 case CachedResource::LinkSubresource:
265 // Prefetch cannot affect the current document. 270 // Prefetch cannot affect the current document.
266 break; 271 break;
267 } 272 }
268 return true; 273 return true;
269 } 274 }
270 275
271 bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url , bool forPreload) 276 bool CachedResourceLoader::checkNonceFromInitiatorElement(const Element* initiat orElement)
277 {
278 return initiatorElement && m_document->contentSecurityPolicy()->allowNonce(i nitiatorElement->fastGetAttribute(HTMLNames::nonceAttr));
abarth-chromium 2013/05/16 00:59:27 This isn't right. Different types have different
jww 2013/05/16 20:59:00 Okay, I think I've basically factored all of the c
279 }
280
281 bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url , bool validNonce, bool forPreload)
272 { 282 {
273 if (document() && !document()->securityOrigin()->canDisplay(url)) { 283 if (document() && !document()->securityOrigin()->canDisplay(url)) {
274 if (!forPreload) 284 if (!forPreload)
275 FrameLoader::reportLocalLoadFailed(frame(), url.elidedString()); 285 FrameLoader::reportLocalLoadFailed(frame(), url.elidedString());
276 LOG(ResourceLoading, "CachedResourceLoader::requestResource URL was not allowed by SecurityOrigin::canDisplay"); 286 LOG(ResourceLoading, "CachedResourceLoader::requestResource URL was not allowed by SecurityOrigin::canDisplay");
277 return 0; 287 return 0;
278 } 288 }
279 289
280 // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. 290 // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved.
281 bool shouldBypassMainWorldContentSecurityPolicy = (frame() && frame()->scrip t()->shouldBypassMainWorldContentSecurityPolicy()); 291 bool shouldBypassMainWorldContentSecurityPolicy = (frame() && frame()->scrip t()->shouldBypassMainWorldContentSecurityPolicy());
(...skipping 21 matching lines...) Expand all
303 case CachedResource::XSLStyleSheet: 313 case CachedResource::XSLStyleSheet:
304 if (!m_document->securityOrigin()->canRequest(url)) { 314 if (!m_document->securityOrigin()->canRequest(url)) {
305 printAccessDeniedMessage(url); 315 printAccessDeniedMessage(url);
306 return false; 316 return false;
307 } 317 }
308 break; 318 break;
309 } 319 }
310 320
311 switch (type) { 321 switch (type) {
312 case CachedResource::XSLStyleSheet: 322 case CachedResource::XSLStyleSheet:
313 if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentS ecurityPolicy()->allowScriptFromSource(url)) 323 if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentS ecurityPolicy()->allowScriptFromSource(url, validNonce))
314 return false; 324 return false;
315 break; 325 break;
316 case CachedResource::Script: 326 case CachedResource::Script:
317 if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentS ecurityPolicy()->allowScriptFromSource(url)) 327 if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentS ecurityPolicy()->allowScriptFromSource(url, validNonce))
318 return false; 328 return false;
319 329
320 if (frame()) { 330 if (frame()) {
321 Settings* settings = frame()->settings(); 331 Settings* settings = frame()->settings();
322 if (!frame()->loader()->client()->allowScriptFromSource(!settings || settings->isScriptEnabled(), url)) { 332 if (!frame()->loader()->client()->allowScriptFromSource(!settings || settings->isScriptEnabled(), url)) {
323 frame()->loader()->client()->didNotAllowScript(); 333 frame()->loader()->client()->didNotAllowScript();
324 return false; 334 return false;
325 } 335 }
326 } 336 }
327 break; 337 break;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 KURL url = request.resourceRequest().url(); 382 KURL url = request.resourceRequest().url();
373 383
374 LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '% s', priority=%d, forPreload=%u", url.elidedString().latin1().data(), request.cha rset().latin1().data(), request.priority(), request.forPreload()); 384 LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '% s', priority=%d, forPreload=%u", url.elidedString().latin1().data(), request.cha rset().latin1().data(), request.priority(), request.forPreload());
375 385
376 // If only the fragment identifiers differ, it is the same resource. 386 // If only the fragment identifiers differ, it is the same resource.
377 url = MemoryCache::removeFragmentIdentifierIfNeeded(url); 387 url = MemoryCache::removeFragmentIdentifierIfNeeded(url);
378 388
379 if (!url.isValid()) 389 if (!url.isValid())
380 return 0; 390 return 0;
381 391
382 if (!canRequest(type, url, request.forPreload())) 392 if (!canRequest(type, url, checkNonceFromInitiatorElement(request.initiatorE lement().get()), request.forPreload()))
abarth-chromium 2013/05/16 00:59:27 This needs to be done in type-specific code becaus
jww 2013/05/16 20:59:00 Done.
383 return 0; 393 return 0;
384 394
385 if (Frame* f = frame()) 395 if (Frame* f = frame())
386 f->loader()->client()->dispatchWillRequestResource(&request); 396 f->loader()->client()->dispatchWillRequestResource(&request);
387 397
388 if (memoryCache()->disabled()) { 398 if (memoryCache()->disabled()) {
389 DocumentResourceMap::iterator it = m_documentResources.find(url.string() ); 399 DocumentResourceMap::iterator it = m_documentResources.find(url.string() );
390 if (it != m_documentResources.end()) { 400 if (it != m_documentResources.end()) {
391 it->value->setOwningCachedResourceLoader(0); 401 it->value->setOwningCachedResourceLoader(0);
392 m_documentResources.remove(it); 402 m_documentResources.remove(it);
(...skipping 20 matching lines...) Expand all
413 break; 423 break;
414 } 424 }
415 425
416 if (!resource) 426 if (!resource)
417 return 0; 427 return 0;
418 428
419 if (!request.forPreload() || policy != Use) 429 if (!request.forPreload() || policy != Use)
420 resource->setLoadPriority(request.priority()); 430 resource->setLoadPriority(request.priority());
421 431
422 if ((policy != Use || resource->stillNeedsLoad()) && CachedResourceRequest:: NoDefer == request.defer()) { 432 if ((policy != Use || resource->stillNeedsLoad()) && CachedResourceRequest:: NoDefer == request.defer()) {
423 resource->load(this, request.options()); 433 ResourceLoaderOptions options(request.options());
434 if (checkNonceFromInitiatorElement(request.initiatorElement().get()))
435 options.cspNonce = NonceCheckValid;
436 resource->load(this, options);
424 437
425 // We don't support immediate loads, but we do support immediate failure . 438 // We don't support immediate loads, but we do support immediate failure .
426 if (resource->errorOccurred()) { 439 if (resource->errorOccurred()) {
427 if (resource->inCache()) 440 if (resource->inCache())
428 memoryCache()->remove(resource.get()); 441 memoryCache()->remove(resource.get());
429 return 0; 442 return 0;
430 } 443 }
431 } 444 }
432 445
433 // FIXME: Temporarily leave main resource caching disabled for chromium, see https://bugs.webkit.org/show_bug.cgi?id=107962 446 // FIXME: Temporarily leave main resource caching disabled for chromium, see https://bugs.webkit.org/show_bug.cgi?id=107962
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 info.addMember(m_validatedURLs, "validatedURLs"); 935 info.addMember(m_validatedURLs, "validatedURLs");
923 info.addMember(m_preloads, "preloads"); 936 info.addMember(m_preloads, "preloads");
924 info.addMember(m_pendingPreloads, "pendingPreloads"); 937 info.addMember(m_pendingPreloads, "pendingPreloads");
925 info.addMember(m_garbageCollectDocumentResourcesTimer, "garbageCollectDocume ntResourcesTimer"); 938 info.addMember(m_garbageCollectDocumentResourcesTimer, "garbageCollectDocume ntResourcesTimer");
926 // FIXME: m_initiatorMap has pointers to already deleted CachedResources 939 // FIXME: m_initiatorMap has pointers to already deleted CachedResources
927 info.ignoreMember(m_initiatorMap); 940 info.ignoreMember(m_initiatorMap);
928 } 941 }
929 942
930 const ResourceLoaderOptions& CachedResourceLoader::defaultCachedResourceOptions( ) 943 const ResourceLoaderOptions& CachedResourceLoader::defaultCachedResourceOptions( )
931 { 944 {
932 static ResourceLoaderOptions options(SendCallbacks, SniffContent, BufferData , AllowStoredCredentials, AskClientForCrossOriginCredentials, DoSecurityCheck); 945 static ResourceLoaderOptions options(SendCallbacks, SniffContent, BufferData , AllowStoredCredentials, AskClientForCrossOriginCredentials, DoSecurityCheck, N onceCheckNotValid);
933 return options; 946 return options;
934 } 947 }
935 948
936 } 949 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698