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

Side by Side Diff: Source/web/WebEmbeddedWorkerImpl.cpp

Issue 1308703002: Block Service Workers containing parts of their query string as XSS. Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 4 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) 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
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
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
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
OLDNEW
« Source/web/WebEmbeddedWorkerImpl.h ('K') | « Source/web/WebEmbeddedWorkerImpl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698