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 |