Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "web/WebEmbeddedWorkerImpl.h" | 32 #include "web/WebEmbeddedWorkerImpl.h" |
| 33 | 33 |
| 34 #include "core/dom/CrossThreadTask.h" | 34 #include "core/dom/CrossThreadTask.h" |
| 35 #include "core/dom/Document.h" | 35 #include "core/dom/Document.h" |
| 36 #include "core/fetch/SubstituteData.h" | 36 #include "core/fetch/SubstituteData.h" |
| 37 #include "core/frame/csp/ContentSecurityPolicy.h" | 37 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 38 #include "core/inspector/ConsoleMessage.h" | |
| 38 #include "core/inspector/InspectorInstrumentation.h" | 39 #include "core/inspector/InspectorInstrumentation.h" |
| 39 #include "core/inspector/WorkerDebuggerAgent.h" | 40 #include "core/inspector/WorkerDebuggerAgent.h" |
| 40 #include "core/inspector/WorkerInspectorController.h" | 41 #include "core/inspector/WorkerInspectorController.h" |
| 41 #include "core/loader/FrameLoadRequest.h" | 42 #include "core/loader/FrameLoadRequest.h" |
| 42 #include "core/workers/WorkerClients.h" | 43 #include "core/workers/WorkerClients.h" |
| 43 #include "core/workers/WorkerGlobalScope.h" | 44 #include "core/workers/WorkerGlobalScope.h" |
| 44 #include "core/workers/WorkerInspectorProxy.h" | 45 #include "core/workers/WorkerInspectorProxy.h" |
| 45 #include "core/workers/WorkerLoaderProxy.h" | 46 #include "core/workers/WorkerLoaderProxy.h" |
| 46 #include "core/workers/WorkerScriptLoader.h" | 47 #include "core/workers/WorkerScriptLoader.h" |
| 47 #include "core/workers/WorkerThreadStartupData.h" | 48 #include "core/workers/WorkerThreadStartupData.h" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 62 #include "public/web/WebWorkerContentSettingsClientProxy.h" | 63 #include "public/web/WebWorkerContentSettingsClientProxy.h" |
| 63 #include "web/ServiceWorkerGlobalScopeClientImpl.h" | 64 #include "web/ServiceWorkerGlobalScopeClientImpl.h" |
| 64 #include "web/ServiceWorkerGlobalScopeProxy.h" | 65 #include "web/ServiceWorkerGlobalScopeProxy.h" |
| 65 #include "web/WebDataSourceImpl.h" | 66 #include "web/WebDataSourceImpl.h" |
| 66 #include "web/WebLocalFrameImpl.h" | 67 #include "web/WebLocalFrameImpl.h" |
| 67 #include "web/WorkerContentSettingsClient.h" | 68 #include "web/WorkerContentSettingsClient.h" |
| 68 #include "wtf/Functional.h" | 69 #include "wtf/Functional.h" |
| 69 | 70 |
| 70 namespace blink { | 71 namespace blink { |
| 71 | 72 |
| 73 namespace { | |
| 74 | |
| 75 bool IsAmpersandOrEqualsSign(UChar character) | |
| 76 { | |
| 77 return character == '=' || character == '&'; | |
| 78 } | |
| 79 | |
| 80 } // namespace | |
| 81 | |
| 72 WebEmbeddedWorker* WebEmbeddedWorker::create(WebServiceWorkerContextClient* clie nt, WebWorkerContentSettingsClientProxy* contentSettingsClient) | 82 WebEmbeddedWorker* WebEmbeddedWorker::create(WebServiceWorkerContextClient* clie nt, WebWorkerContentSettingsClientProxy* contentSettingsClient) |
| 73 { | 83 { |
| 74 return new WebEmbeddedWorkerImpl(adoptPtr(client), adoptPtr(contentSettingsC lient)); | 84 return new WebEmbeddedWorkerImpl(adoptPtr(client), adoptPtr(contentSettingsC lient)); |
| 75 } | 85 } |
| 76 | 86 |
| 77 static HashSet<WebEmbeddedWorkerImpl*>& runningWorkerInstances() | 87 static HashSet<WebEmbeddedWorkerImpl*>& runningWorkerInstances() |
| 78 { | 88 { |
| 79 DEFINE_STATIC_LOCAL(HashSet<WebEmbeddedWorkerImpl*>, set, ()); | 89 DEFINE_STATIC_LOCAL(HashSet<WebEmbeddedWorkerImpl*>, set, ()); |
| 80 return set; | 90 return set; |
| 81 } | 91 } |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 return; | 312 return; |
| 303 } | 313 } |
| 304 | 314 |
| 305 Platform::current()->histogramCustomCounts("ServiceWorker.ScriptSize", m_mai nScriptLoader->script().length(), 1000, 5000000, 50); | 315 Platform::current()->histogramCustomCounts("ServiceWorker.ScriptSize", m_mai nScriptLoader->script().length(), 1000, 5000000, 50); |
| 306 if (m_mainScriptLoader->cachedMetadata()) | 316 if (m_mainScriptLoader->cachedMetadata()) |
| 307 Platform::current()->histogramCustomCounts("ServiceWorker.ScriptCachedMe tadataSize", m_mainScriptLoader->cachedMetadata()->size(), 1000, 50000000, 50); | 317 Platform::current()->histogramCustomCounts("ServiceWorker.ScriptCachedMe tadataSize", m_mainScriptLoader->cachedMetadata()->size(), 1000, 50000000, 50); |
| 308 | 318 |
| 309 startWorkerThread(); | 319 startWorkerThread(); |
| 310 } | 320 } |
| 311 | 321 |
| 322 String WebEmbeddedWorkerImpl::checkForReflectedXSS() | |
| 323 { | |
| 324 ASSERT(m_mainScriptLoader); | |
| 325 | |
| 326 String queryString = m_mainScriptLoader->url().query(); | |
| 327 String script = m_mainScriptLoader->script(); | |
| 328 String segment, decoded; | |
| 329 size_t offset = 0, next; | |
| 330 | |
| 331 do { | |
| 332 next = queryString.find(IsAmpersandOrEqualsSign, offset); | |
| 333 if (next == kNotFound) { | |
| 334 segment = queryString.substring(offset); | |
| 335 } else { | |
| 336 offset = next + 1; | |
| 337 segment = queryString.substring(offset, next - offset); | |
| 338 } | |
| 339 if (segment.sizeInBytes() > 20) { | |
|
Tom Sepez
2015/08/31 16:41:19
why 20?
| |
| 340 decoded = decodeURLEscapeSequences(segment); | |
| 341 if (script.contains(segment)) { | |
|
Tom Sepez
2015/08/31 16:41:19
what about multiple decodings? e.g. %2525332 etc.
| |
| 342 return segment; | |
| 343 } | |
| 344 if (script.contains(decoded)) { | |
| 345 return decoded; | |
| 346 } | |
| 347 } | |
| 348 } while (next != kNotFound); | |
| 349 | |
| 350 return ""; | |
| 351 } | |
| 352 | |
| 312 void WebEmbeddedWorkerImpl::startWorkerThread() | 353 void WebEmbeddedWorkerImpl::startWorkerThread() |
| 313 { | 354 { |
| 314 ASSERT(!m_askedToTerminate); | 355 ASSERT(!m_askedToTerminate); |
| 315 | 356 |
| 316 Document* document = m_mainFrame->frame()->document(); | 357 Document* document = m_mainFrame->frame()->document(); |
| 317 | 358 |
| 318 WorkerThreadStartMode startMode = DontPauseWorkerGlobalScopeOnStart; | 359 WorkerThreadStartMode startMode = DontPauseWorkerGlobalScopeOnStart; |
| 319 if (InspectorInstrumentation::shouldPauseDedicatedWorkerOnStart(document)) | 360 if (InspectorInstrumentation::shouldPauseDedicatedWorkerOnStart(document)) |
| 320 startMode = PauseWorkerGlobalScopeOnStart; | 361 startMode = PauseWorkerGlobalScopeOnStart; |
| 321 | 362 |
| 322 // FIXME: this document's origin is pristine and without any extra privilege s. (crbug.com/254993) | 363 // FIXME: this document's origin is pristine and without any extra privilege s. (crbug.com/254993) |
| 323 SecurityOrigin* starterOrigin = document->securityOrigin(); | 364 SecurityOrigin* starterOrigin = document->securityOrigin(); |
| 324 | 365 |
| 325 OwnPtrWillBeRawPtr<WorkerClients> workerClients = WorkerClients::create(); | 366 OwnPtrWillBeRawPtr<WorkerClients> workerClients = WorkerClients::create(); |
| 326 provideContentSettingsClientToWorker(workerClients.get(), m_contentSettingsC lient.release()); | 367 provideContentSettingsClientToWorker(workerClients.get(), m_contentSettingsC lient.release()); |
| 327 provideServiceWorkerGlobalScopeClientToWorker(workerClients.get(), ServiceWo rkerGlobalScopeClientImpl::create(*m_workerContextClient)); | 368 provideServiceWorkerGlobalScopeClientToWorker(workerClients.get(), ServiceWo rkerGlobalScopeClientImpl::create(*m_workerContextClient)); |
| 328 provideServiceWorkerContainerClientToWorker(workerClients.get(), adoptPtr(m_ workerContextClient->createServiceWorkerProvider())); | 369 provideServiceWorkerContainerClientToWorker(workerClients.get(), adoptPtr(m_ workerContextClient->createServiceWorkerProvider())); |
| 329 | 370 |
| 330 // We need to set the CSP to both the shadow page's document and the Service WorkerGlobalScope. | 371 // We need to set the CSP to both the shadow page's document and the Service WorkerGlobalScope. |
| 331 document->initContentSecurityPolicy(m_mainScriptLoader->releaseContentSecuri tyPolicy()); | 372 document->initContentSecurityPolicy(m_mainScriptLoader->releaseContentSecuri tyPolicy()); |
| 332 | 373 |
| 374 // Verify that the query string contains nothing bad. | |
| 375 String script = m_mainScriptLoader->script(); | |
| 376 String potentialXSS = checkForReflectedXSS(); | |
| 377 if (potentialXSS != "") { | |
| 378 document->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource , ErrorMessageLevel, "Service Worker script invocation blocked; contained \"" + potentialXSS + "\", which was a query string parameter.")); | |
| 379 m_workerContextClient->workerContextFailedToStart(); | |
| 380 return; | |
| 381 } | |
| 382 | |
| 333 KURL scriptURL = m_mainScriptLoader->url(); | 383 KURL scriptURL = m_mainScriptLoader->url(); |
| 334 OwnPtr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::creat e( | 384 OwnPtr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::creat e( |
| 335 scriptURL, | 385 scriptURL, |
| 336 m_workerStartData.userAgent, | 386 m_workerStartData.userAgent, |
| 337 m_mainScriptLoader->script(), | 387 script, |
| 338 m_mainScriptLoader->releaseCachedMetadata(), | 388 m_mainScriptLoader->releaseCachedMetadata(), |
| 339 startMode, | 389 startMode, |
| 340 document->contentSecurityPolicy()->headers(), | 390 document->contentSecurityPolicy()->headers(), |
| 341 starterOrigin, | 391 starterOrigin, |
| 342 workerClients.release(), | 392 workerClients.release(), |
| 343 static_cast<V8CacheOptions>(m_workerStartData.v8CacheOptions)); | 393 static_cast<V8CacheOptions>(m_workerStartData.v8CacheOptions)); |
| 344 | 394 |
| 345 m_mainScriptLoader.clear(); | 395 m_mainScriptLoader.clear(); |
| 346 | 396 |
| 347 m_workerGlobalScopeProxy = ServiceWorkerGlobalScopeProxy::create(*this, *doc ument, *m_workerContextClient); | 397 m_workerGlobalScopeProxy = ServiceWorkerGlobalScopeProxy::create(*this, *doc ument, *m_workerContextClient); |
| 348 m_loaderProxy = WorkerLoaderProxy::create(this); | 398 m_loaderProxy = WorkerLoaderProxy::create(this); |
| 349 m_workerThread = ServiceWorkerThread::create(m_loaderProxy, *m_workerGlobalS copeProxy); | 399 m_workerThread = ServiceWorkerThread::create(m_loaderProxy, *m_workerGlobalS copeProxy); |
| 350 m_workerThread->start(startupData.release()); | 400 m_workerThread->start(startupData.release()); |
| 351 m_workerInspectorProxy->workerThreadCreated(document, m_workerThread.get(), scriptURL); | 401 m_workerInspectorProxy->workerThreadCreated(document, m_workerThread.get(), scriptURL); |
| 352 } | 402 } |
| 353 | 403 |
| 354 } // namespace blink | 404 } // namespace blink |
| OLD | NEW |