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

Side by Side Diff: third_party/WebKit/Source/core/loader/MixedContentChecker.cpp

Issue 2625633002: Supporting changes in preparation of browser side mixed content checking. (Closed)
Patch Set: Address code review comments. Created 3 years, 11 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) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 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 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 25 matching lines...) Expand all
36 #include "core/inspector/ConsoleMessage.h" 36 #include "core/inspector/ConsoleMessage.h"
37 #include "core/loader/DocumentLoader.h" 37 #include "core/loader/DocumentLoader.h"
38 #include "core/loader/FrameLoader.h" 38 #include "core/loader/FrameLoader.h"
39 #include "core/loader/FrameLoaderClient.h" 39 #include "core/loader/FrameLoaderClient.h"
40 #include "platform/RuntimeEnabledFeatures.h" 40 #include "platform/RuntimeEnabledFeatures.h"
41 #include "platform/network/NetworkUtils.h" 41 #include "platform/network/NetworkUtils.h"
42 #include "platform/weborigin/SchemeRegistry.h" 42 #include "platform/weborigin/SchemeRegistry.h"
43 #include "platform/weborigin/SecurityOrigin.h" 43 #include "platform/weborigin/SecurityOrigin.h"
44 #include "public/platform/WebAddressSpace.h" 44 #include "public/platform/WebAddressSpace.h"
45 #include "public/platform/WebInsecureRequestPolicy.h" 45 #include "public/platform/WebInsecureRequestPolicy.h"
46 #include "public/platform/WebMixedContent.h"
46 #include "wtf/text/StringBuilder.h" 47 #include "wtf/text/StringBuilder.h"
47 48
48 namespace blink { 49 namespace blink {
49 50
50 namespace { 51 namespace {
51 52
52 // When a frame is local, use its full URL to represent the main resource. When 53 // When a frame is local, use its full URL to represent the main resource. When
53 // the frame is remote, the full URL isn't accessible, so use the origin. This 54 // the frame is remote, the full URL isn't accessible, so use the origin. This
54 // function is used, for example, to determine the URL to show in console 55 // function is used, for example, to determine the URL to show in console
55 // messages about mixed content. 56 // messages about mixed content.
56 KURL mainResourceUrlForFrame(Frame* frame) { 57 KURL mainResourceUrlForFrame(Frame* frame) {
57 if (frame->isRemoteFrame()) { 58 if (frame->isRemoteFrame()) {
58 return KURL(KURL(), 59 return KURL(KURL(),
59 frame->securityContext()->getSecurityOrigin()->toString()); 60 frame->securityContext()->getSecurityOrigin()->toString());
60 } 61 }
61 return toLocalFrame(frame)->document()->url(); 62 return toLocalFrame(frame)->document()->url();
62 } 63 }
63 64
65 const char* requestContextName(WebURLRequest::RequestContext context) {
66 switch (context) {
67 case WebURLRequest::RequestContextAudio:
68 return "audio file";
69 case WebURLRequest::RequestContextBeacon:
70 return "Beacon endpoint";
71 case WebURLRequest::RequestContextCSPReport:
72 return "Content Security Policy reporting endpoint";
73 case WebURLRequest::RequestContextDownload:
74 return "download";
75 case WebURLRequest::RequestContextEmbed:
76 return "plugin resource";
77 case WebURLRequest::RequestContextEventSource:
78 return "EventSource endpoint";
79 case WebURLRequest::RequestContextFavicon:
80 return "favicon";
81 case WebURLRequest::RequestContextFetch:
82 return "resource";
83 case WebURLRequest::RequestContextFont:
84 return "font";
85 case WebURLRequest::RequestContextForm:
86 return "form action";
87 case WebURLRequest::RequestContextFrame:
88 return "frame";
89 case WebURLRequest::RequestContextHyperlink:
90 return "resource";
91 case WebURLRequest::RequestContextIframe:
92 return "frame";
93 case WebURLRequest::RequestContextImage:
94 return "image";
95 case WebURLRequest::RequestContextImageSet:
96 return "image";
97 case WebURLRequest::RequestContextImport:
98 return "HTML Import";
99 case WebURLRequest::RequestContextInternal:
100 return "resource";
101 case WebURLRequest::RequestContextLocation:
102 return "resource";
103 case WebURLRequest::RequestContextManifest:
104 return "manifest";
105 case WebURLRequest::RequestContextObject:
106 return "plugin resource";
107 case WebURLRequest::RequestContextPing:
108 return "hyperlink auditing endpoint";
109 case WebURLRequest::RequestContextPlugin:
110 return "plugin data";
111 case WebURLRequest::RequestContextPrefetch:
112 return "prefetch resource";
113 case WebURLRequest::RequestContextScript:
114 return "script";
115 case WebURLRequest::RequestContextServiceWorker:
116 return "Service Worker script";
117 case WebURLRequest::RequestContextSharedWorker:
118 return "Shared Worker script";
119 case WebURLRequest::RequestContextStyle:
120 return "stylesheet";
121 case WebURLRequest::RequestContextSubresource:
122 return "resource";
123 case WebURLRequest::RequestContextTrack:
124 return "Text Track";
125 case WebURLRequest::RequestContextUnspecified:
126 return "resource";
127 case WebURLRequest::RequestContextVideo:
128 return "video";
129 case WebURLRequest::RequestContextWorker:
130 return "Worker script";
131 case WebURLRequest::RequestContextXMLHttpRequest:
132 return "XMLHttpRequest endpoint";
133 case WebURLRequest::RequestContextXSLT:
134 return "XSLT";
135 }
136 NOTREACHED();
137 return "resource";
138 }
139
64 } // namespace 140 } // namespace
65 141
66 static void measureStricterVersionOfIsMixedContent(Frame* frame, 142 static void measureStricterVersionOfIsMixedContent(Frame* frame,
67 const KURL& url) { 143 const KURL& url) {
68 // We're currently only checking for mixed content in `https://*` contexts. 144 // We're currently only checking for mixed content in `https://*` contexts.
69 // What about other "secure" contexts the SchemeRegistry knows about? We'll 145 // What about other "secure" contexts the SchemeRegistry knows about? We'll
70 // use this method to measure the occurance of non-webby mixed content to make 146 // use this method to measure the occurance of non-webby mixed content to make
71 // sure we're not breaking the world without realizing it. 147 // sure we're not breaking the world without realizing it.
72 SecurityOrigin* origin = frame->securityContext()->getSecurityOrigin(); 148 SecurityOrigin* origin = frame->securityContext()->getSecurityOrigin();
73 if (MixedContentChecker::isMixedContent(origin, url)) { 149 if (MixedContentChecker::isMixedContent(origin, url)) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 void MixedContentChecker::logToConsoleAboutFetch( 219 void MixedContentChecker::logToConsoleAboutFetch(
144 LocalFrame* frame, 220 LocalFrame* frame,
145 const KURL& mainResourceUrl, 221 const KURL& mainResourceUrl,
146 const KURL& url, 222 const KURL& url,
147 WebURLRequest::RequestContext requestContext, 223 WebURLRequest::RequestContext requestContext,
148 bool allowed) { 224 bool allowed) {
149 String message = String::format( 225 String message = String::format(
150 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an " 226 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an "
151 "insecure %s '%s'. %s", 227 "insecure %s '%s'. %s",
152 mainResourceUrl.elidedString().utf8().data(), 228 mainResourceUrl.elidedString().utf8().data(),
153 WebMixedContent::requestContextName(requestContext), 229 requestContextName(requestContext), url.elidedString().utf8().data(),
154 url.elidedString().utf8().data(),
155 allowed ? "This content should also be served over HTTPS." 230 allowed ? "This content should also be served over HTTPS."
156 : "This request has been blocked; the content must be served " 231 : "This request has been blocked; the content must be served "
157 "over HTTPS."); 232 "over HTTPS.");
158 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLevel; 233 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLevel;
159 frame->document()->addConsoleMessage( 234 frame->document()->addConsoleMessage(
160 ConsoleMessage::create(SecurityMessageSource, messageLevel, message)); 235 ConsoleMessage::create(SecurityMessageSource, messageLevel, message));
161 } 236 }
162 237
163 // static 238 // static
164 void MixedContentChecker::count(Frame* frame, 239 void MixedContentChecker::count(Frame* frame,
165 WebURLRequest::RequestContext requestContext) { 240 WebURLRequest::RequestContext requestContext) {
166 UseCounter::count(frame, UseCounter::MixedContentPresent); 241 UseCounter::count(frame, UseCounter::MixedContentPresent);
167 242
168 // Roll blockable content up into a single counter, count unblocked types 243 // Roll blockable content up into a single counter, count unblocked types
169 // individually so we can determine when they can be safely moved to the 244 // individually so we can determine when they can be safely moved to the
170 // blockable category: 245 // blockable category:
171 WebMixedContent::ContextType contextType = 246 WebMixedContentContextType contextType =
172 WebMixedContent::contextTypeFromRequestContext( 247 WebMixedContent::contextTypeFromRequestContext(
173 requestContext, 248 requestContext,
174 frame->settings()->getStrictMixedContentCheckingForPlugin()); 249 frame->settings()->getStrictMixedContentCheckingForPlugin());
175 if (contextType == WebMixedContent::ContextType::Blockable) { 250 if (contextType == WebMixedContentContextType::Blockable) {
176 UseCounter::count(frame, UseCounter::MixedContentBlockable); 251 UseCounter::count(frame, UseCounter::MixedContentBlockable);
177 return; 252 return;
178 } 253 }
179 254
180 UseCounter::Feature feature; 255 UseCounter::Feature feature;
181 switch (requestContext) { 256 switch (requestContext) {
182 case WebURLRequest::RequestContextAudio: 257 case WebURLRequest::RequestContextAudio:
183 feature = UseCounter::MixedContentAudio; 258 feature = UseCounter::MixedContentAudio;
184 break; 259 break;
185 case WebURLRequest::RequestContextDownload: 260 case WebURLRequest::RequestContextDownload:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 mixedFrame->securityContext()->getSecurityOrigin(); 313 mixedFrame->securityContext()->getSecurityOrigin();
239 bool allowed = false; 314 bool allowed = false;
240 315
241 // If we're in strict mode, we'll automagically fail everything, and 316 // If we're in strict mode, we'll automagically fail everything, and
242 // intentionally skip the client checks in order to prevent degrading the 317 // intentionally skip the client checks in order to prevent degrading the
243 // site's security UI. 318 // site's security UI.
244 bool strictMode = mixedFrame->securityContext()->getInsecureRequestPolicy() & 319 bool strictMode = mixedFrame->securityContext()->getInsecureRequestPolicy() &
245 kBlockAllMixedContent || 320 kBlockAllMixedContent ||
246 settings->getStrictMixedContentChecking(); 321 settings->getStrictMixedContentChecking();
247 322
248 WebMixedContent::ContextType contextType = 323 WebMixedContentContextType contextType =
249 WebMixedContent::contextTypeFromRequestContext( 324 WebMixedContent::contextTypeFromRequestContext(
250 requestContext, settings->getStrictMixedContentCheckingForPlugin()); 325 requestContext, settings->getStrictMixedContentCheckingForPlugin());
251 326
252 // If we're loading the main resource of a subframe, we need to take a close 327 // If we're loading the main resource of a subframe, we need to take a close
253 // look at the loaded URL. If we're dealing with a CORS-enabled scheme, then 328 // look at the loaded URL. If we're dealing with a CORS-enabled scheme, then
254 // block mixed frames as active content. Otherwise, treat frames as passive 329 // block mixed frames as active content. Otherwise, treat frames as passive
255 // content. 330 // content.
256 // 331 //
257 // FIXME: Remove this temporary hack once we have a reasonable API for 332 // FIXME: Remove this temporary hack once we have a reasonable API for
258 // launching external applications via URLs. http://crbug.com/318788 and 333 // launching external applications via URLs. http://crbug.com/318788 and
259 // https://crbug.com/393481 334 // https://crbug.com/393481
260 if (frameType == WebURLRequest::FrameTypeNested && 335 if (frameType == WebURLRequest::FrameTypeNested &&
261 !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(url.protocol())) 336 !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(url.protocol()))
262 contextType = WebMixedContent::ContextType::OptionallyBlockable; 337 contextType = WebMixedContentContextType::OptionallyBlockable;
263 338
264 switch (contextType) { 339 switch (contextType) {
265 case WebMixedContent::ContextType::OptionallyBlockable: 340 case WebMixedContentContextType::OptionallyBlockable:
266 allowed = !strictMode; 341 allowed = !strictMode;
267 if (allowed) { 342 if (allowed) {
268 client->passiveInsecureContentFound(url); 343 client->passiveInsecureContentFound(url);
269 client->didDisplayInsecureContent(); 344 client->didDisplayInsecureContent();
270 } 345 }
271 break; 346 break;
272 347
273 case WebMixedContent::ContextType::Blockable: { 348 case WebMixedContentContextType::Blockable: {
274 // Strictly block subresources that are mixed with respect to their 349 // Strictly block subresources that are mixed with respect to their
275 // subframes, unless all insecure content is allowed. This is to avoid the 350 // subframes, unless all insecure content is allowed. This is to avoid the
276 // following situation: https://a.com embeds https://b.com, which loads a 351 // following situation: https://a.com embeds https://b.com, which loads a
277 // script over insecure HTTP. The user opts to allow the insecure content, 352 // script over insecure HTTP. The user opts to allow the insecure content,
278 // thinking that they are allowing an insecure script to run on 353 // thinking that they are allowing an insecure script to run on
279 // https://a.com and not realizing that they are in fact allowing an 354 // https://a.com and not realizing that they are in fact allowing an
280 // insecure script on https://b.com. 355 // insecure script on https://b.com.
281 if (!settings->getAllowRunningOfInsecureContent() && 356 if (!settings->getAllowRunningOfInsecureContent() &&
282 requestIsSubframeSubresource(effectiveFrame, frameType) && 357 requestIsSubframeSubresource(effectiveFrame, frameType) &&
283 isMixedContent(frame->securityContext()->getSecurityOrigin(), url)) { 358 isMixedContent(frame->securityContext()->getSecurityOrigin(), url)) {
(...skipping 11 matching lines...) Expand all
295 client->allowRunningInsecureContent( 370 client->allowRunningInsecureContent(
296 settings && settings->getAllowRunningOfInsecureContent(), 371 settings && settings->getAllowRunningOfInsecureContent(),
297 securityOrigin, url); 372 securityOrigin, url);
298 if (allowed) { 373 if (allowed) {
299 client->didRunInsecureContent(securityOrigin, url); 374 client->didRunInsecureContent(securityOrigin, url);
300 UseCounter::count(mixedFrame, UseCounter::MixedContentBlockableAllowed); 375 UseCounter::count(mixedFrame, UseCounter::MixedContentBlockableAllowed);
301 } 376 }
302 break; 377 break;
303 } 378 }
304 379
305 case WebMixedContent::ContextType::ShouldBeBlockable: 380 case WebMixedContentContextType::ShouldBeBlockable:
306 allowed = !strictMode; 381 allowed = !strictMode;
307 if (allowed) 382 if (allowed)
308 client->didDisplayInsecureContent(); 383 client->didDisplayInsecureContent();
309 break; 384 break;
310 case WebMixedContent::ContextType::NotMixedContent: 385 case WebMixedContentContextType::NotMixedContent:
311 NOTREACHED(); 386 NOTREACHED();
312 break; 387 break;
313 }; 388 };
314 389
315 if (reportingStatus == SendReport) { 390 if (reportingStatus == SendReport) {
316 logToConsoleAboutFetch(frame, mainResourceUrlForFrame(mixedFrame), url, 391 logToConsoleAboutFetch(frame, mainResourceUrlForFrame(mixedFrame), url,
317 requestContext, allowed); 392 requestContext, allowed);
318 } 393 }
319 return !allowed; 394 return !allowed;
320 } 395 }
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); 543 Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType);
469 if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame) 544 if (frameType == WebURLRequest::FrameTypeTopLevel || !effectiveFrame)
470 return; 545 return;
471 546
472 // Use the current local frame's client; the embedder doesn't distinguish 547 // Use the current local frame's client; the embedder doesn't distinguish
473 // mixed content signals from different frames on the same page. 548 // mixed content signals from different frames on the same page.
474 FrameLoaderClient* client = frame->loader().client(); 549 FrameLoaderClient* client = frame->loader().client();
475 bool strictMixedContentCheckingForPlugin = 550 bool strictMixedContentCheckingForPlugin =
476 effectiveFrame->settings() && 551 effectiveFrame->settings() &&
477 effectiveFrame->settings()->getStrictMixedContentCheckingForPlugin(); 552 effectiveFrame->settings()->getStrictMixedContentCheckingForPlugin();
478 WebMixedContent::ContextType contextType = 553 WebMixedContentContextType contextType =
479 WebMixedContent::contextTypeFromRequestContext( 554 WebMixedContent::contextTypeFromRequestContext(
480 requestContext, strictMixedContentCheckingForPlugin); 555 requestContext, strictMixedContentCheckingForPlugin);
481 if (contextType == WebMixedContent::ContextType::Blockable) { 556 if (contextType == WebMixedContentContextType::Blockable) {
482 client->didRunContentWithCertificateErrors(response.url()); 557 client->didRunContentWithCertificateErrors(response.url());
483 } else { 558 } else {
484 // contextTypeFromRequestContext() never returns NotMixedContent (it 559 // contextTypeFromRequestContext() never returns NotMixedContent (it
485 // computes the type of mixed content, given that the content is mixed). 560 // computes the type of mixed content, given that the content is mixed).
486 DCHECK_NE(contextType, WebMixedContent::ContextType::NotMixedContent); 561 DCHECK_NE(contextType, WebMixedContentContextType::NotMixedContent);
487 client->didDisplayContentWithCertificateErrors(response.url()); 562 client->didDisplayContentWithCertificateErrors(response.url());
488 } 563 }
489 } 564 }
490 565
491 WebMixedContent::ContextType MixedContentChecker::contextTypeForInspector( 566 WebMixedContentContextType MixedContentChecker::contextTypeForInspector(
492 LocalFrame* frame, 567 LocalFrame* frame,
493 const ResourceRequest& request) { 568 const ResourceRequest& request) {
494 Frame* effectiveFrame = 569 Frame* effectiveFrame =
495 effectiveFrameForFrameType(frame, request.frameType()); 570 effectiveFrameForFrameType(frame, request.frameType());
496 571
497 Frame* mixedFrame = inWhichFrameIsContentMixed( 572 Frame* mixedFrame = inWhichFrameIsContentMixed(
498 effectiveFrame, request.frameType(), request.url()); 573 effectiveFrame, request.frameType(), request.url());
499 if (!mixedFrame) 574 if (!mixedFrame)
500 return WebMixedContent::ContextType::NotMixedContent; 575 return WebMixedContentContextType::NotMixedContent;
501 576
502 // See comment in shouldBlockFetch() about loading the main resource of a 577 // See comment in shouldBlockFetch() about loading the main resource of a
503 // subframe. 578 // subframe.
504 if (request.frameType() == WebURLRequest::FrameTypeNested && 579 if (request.frameType() == WebURLRequest::FrameTypeNested &&
505 !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled( 580 !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(
506 request.url().protocol())) { 581 request.url().protocol())) {
507 return WebMixedContent::ContextType::OptionallyBlockable; 582 return WebMixedContentContextType::OptionallyBlockable;
508 } 583 }
509 584
510 bool strictMixedContentCheckingForPlugin = 585 bool strictMixedContentCheckingForPlugin =
511 mixedFrame->settings() && 586 mixedFrame->settings() &&
512 mixedFrame->settings()->getStrictMixedContentCheckingForPlugin(); 587 mixedFrame->settings()->getStrictMixedContentCheckingForPlugin();
513 return WebMixedContent::contextTypeFromRequestContext( 588 return WebMixedContent::contextTypeFromRequestContext(
514 request.requestContext(), strictMixedContentCheckingForPlugin); 589 request.requestContext(), strictMixedContentCheckingForPlugin);
515 } 590 }
516 591
517 } // namespace blink 592 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698