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

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

Issue 598533003: Revert "Mixed Content: Make MixedContentChecker completely static." (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 3 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
« no previous file with comments | « Source/core/loader/MixedContentChecker.h ('k') | Source/core/loader/PingLoader.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 27 matching lines...) Expand all
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/weborigin/SchemeRegistry.h" 41 #include "platform/weborigin/SchemeRegistry.h"
42 #include "platform/weborigin/SecurityOrigin.h" 42 #include "platform/weborigin/SecurityOrigin.h"
43 #include "public/platform/Platform.h" 43 #include "public/platform/Platform.h"
44 #include "wtf/text/StringBuilder.h" 44 #include "wtf/text/StringBuilder.h"
45 45
46 namespace blink { 46 namespace blink {
47 47
48 namespace {
49 } // namespace
50
51 MixedContentChecker::MixedContentChecker(LocalFrame* frame)
52 : m_frame(frame)
53 {
54 }
55
56 FrameLoaderClient* MixedContentChecker::client() const
57 {
58 return m_frame->loader().client();
59 }
60
48 // static 61 // static
49 bool MixedContentChecker::isMixedContent(SecurityOrigin* securityOrigin, const K URL& url) 62 bool MixedContentChecker::isMixedContent(SecurityOrigin* securityOrigin, const K URL& url)
50 { 63 {
51 if (securityOrigin->protocol() != "https") 64 if (securityOrigin->protocol() != "https")
52 return false; // We only care about HTTPS security origins. 65 return false; // We only care about HTTPS security origins.
53 66
54 // We're in a secure context, so |url| is mixed content if it's insecure. 67 // We're in a secure context, so |url| is mixed content if it's insecure.
55 return !SecurityOrigin::isSecure(url); 68 return !SecurityOrigin::isSecure(url);
56 } 69 }
57 70
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 case WebURLRequest::RequestContextXSLT: 197 case WebURLRequest::RequestContextXSLT:
185 return "XSLT"; 198 return "XSLT";
186 } 199 }
187 ASSERT_NOT_REACHED(); 200 ASSERT_NOT_REACHED();
188 return "resource"; 201 return "resource";
189 } 202 }
190 203
191 // static 204 // static
192 void MixedContentChecker::logToConsole(LocalFrame* frame, const KURL& url, WebUR LRequest::RequestContext requestContext, bool allowed) 205 void MixedContentChecker::logToConsole(LocalFrame* frame, const KURL& url, WebUR LRequest::RequestContext requestContext, bool allowed)
193 { 206 {
207 String message = String::format(
208 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an insecure %s '%s'. %s",
209 frame->document()->url().elidedString().utf8().data(), typeNameFromConte xt(requestContext), url.elidedString().utf8().data(),
210 allowed ? "This content should also be served over HTTPS." : "This reque st has been blocked; the content must be served over HTTPS.");
211 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve l;
212 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS ource, messageLevel, message));
194 } 213 }
195 214
196 LocalFrame* MixedContentChecker::inWhichFrameIsThisContentMixed(LocalFrame* fram e, WebURLRequest::RequestContext requestContext, WebURLRequest::FrameType frameT ype, const KURL& url) 215 // static
216 bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, const ResourceRequ est& resourceRequest, const KURL& url)
197 { 217 {
198 // No frame, no mixed content: 218 // No frame, no mixed content:
199 if (!frame) 219 if (!frame)
200 return 0; 220 return false;
201
202 // We only care about subresource loads; top-level navigations cannot be mix ed content.
203 if (frameType == WebURLRequest::FrameTypeTopLevel)
204 return 0;
205 221
206 // Check the top frame first. 222 // Check the top frame first.
207 if (Frame* top = frame->tree().top()) { 223 if (Frame* top = frame->tree().top()) {
208 // FIXME: We need a way to access the top-level frame's SecurityOrigin w hen that frame 224 // FIXME: We need a way to access the top-level frame's SecurityOrigin w hen that frame
209 // is in a different process from the current frame. Until that is done, we bail out 225 // is in a different process from the current frame. Until that is done, we bail out
210 // early and allow the load. 226 // early and allow the load.
211 if (!top->isLocalFrame()) 227 if (!top->isLocalFrame())
212 return 0; 228 return false;
213 229
214 LocalFrame* localTop = toLocalFrame(top); 230 LocalFrame* localTop = toLocalFrame(top);
215 if (frame != localTop && inWhichFrameIsThisContentMixed(localTop, reques tContext, frameType, url)) 231 if (frame != localTop && shouldBlockFetch(localTop, resourceRequest, url ))
216 return localTop; 232 return true;
217 } 233 }
218 234
219 // Just count these for the moment, don't block them. 235 // We only care about subresource loads; top-level navigations cannot be mix ed content.
220 if (Platform::current()->isReservedIPAddress(url) && !Platform::current()->i sReservedIPAddress(KURL(ParsedURLString, frame->document()->securityOrigin()->to String()))) 236 if (resourceRequest.frameType() == WebURLRequest::FrameTypeTopLevel)
221 UseCounter::count(frame->document(), contextTypeFromContext(requestConte xt) == ContextTypeBlockable ? UseCounter::MixedContentPrivateIPInPublicWebsiteAc tive : UseCounter::MixedContentPrivateIPInPublicWebsitePassive); 237 return false;
222 238
223 // No mixed content, no problem. 239 // No mixed content, no problem.
224 if (!isMixedContent(frame->document()->securityOrigin(), url)) 240 if (!isMixedContent(frame->document()->securityOrigin(), url))
225 return 0;
226
227 return frame;
228 }
229
230 // static
231 bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::Req uestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url)
232 {
233 LocalFrame* effectiveFrame = inWhichFrameIsThisContentMixed(frame, requestCo ntext, frameType, url);
234 if (!effectiveFrame)
235 return false; 241 return false;
236 242
237 Settings* settings = effectiveFrame->settings(); 243 Settings* settings = frame->settings();
238 FrameLoaderClient* client = effectiveFrame->loader().client(); 244 FrameLoaderClient* client = frame->loader().client();
239 SecurityOrigin* securityOrigin = effectiveFrame->document()->securityOrigin( ); 245 SecurityOrigin* securityOrigin = frame->document()->securityOrigin();
240 bool allowed = false; 246 bool allowed = false;
241 247
242 ContextType contextType = contextTypeFromContext(requestContext); 248 ContextType contextType = contextTypeFromContext(resourceRequest.requestCont ext());
243 if (contextType == ContextTypeBlockableUnlessLax) 249 if (contextType == ContextTypeBlockableUnlessLax)
244 contextType = RuntimeEnabledFeatures::laxMixedContentCheckingEnabled() ? ContextTypeOptionallyBlockable : ContextTypeBlockable; 250 contextType = RuntimeEnabledFeatures::laxMixedContentCheckingEnabled() ? ContextTypeOptionallyBlockable : ContextTypeBlockable;
245 251
246 if (frameType == WebURLRequest::FrameTypeNested) {
247 // For subframes, if we're dealing with a CORS-enabled scheme, then bloc k mixed content. Otherwise,
248 // treat frames as passive content.
249 //
250 // FIXME: Remove this temporary hack once we have a reasonable API for l aunching external applications
251 // via URLs. http://crbug.com/318788 and https://crbug.com/393481
252 contextType = SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(url.prot ocol()) ? ContextTypeBlockable : ContextTypeOptionallyBlockable;
253 }
254
255 switch (contextType) { 252 switch (contextType) {
256 case ContextTypeOptionallyBlockable: 253 case ContextTypeOptionallyBlockable:
257 allowed = client->allowDisplayingInsecureContent(settings && settings->a llowDisplayOfInsecureContent(), securityOrigin, url); 254 allowed = client->allowDisplayingInsecureContent(settings && settings->a llowDisplayOfInsecureContent(), securityOrigin, url);
258 if (allowed) 255 if (allowed)
259 client->didDisplayInsecureContent(); 256 client->didDisplayInsecureContent();
260 break; 257 break;
261 258
262 case ContextTypeBlockable: 259 case ContextTypeBlockable:
263 allowed = client->allowRunningInsecureContent(settings && settings->allo wRunningOfInsecureContent(), securityOrigin, url); 260 allowed = client->allowRunningInsecureContent(settings && settings->allo wRunningOfInsecureContent(), securityOrigin, url);
264 if (allowed) 261 if (allowed)
265 client->didRunInsecureContent(securityOrigin, url); 262 client->didRunInsecureContent(securityOrigin, url);
266 break; 263 break;
267 264
268 case ContextTypeShouldBeBlockable: 265 case ContextTypeShouldBeBlockable:
269 return false; 266 return false;
270 267
271 case ContextTypeBlockableUnlessLax: 268 case ContextTypeBlockableUnlessLax:
272 // We map this to either OptionallyBlockable or Blockable above. 269 // We map this to either OptionallyBlockable or Blockable above.
273 ASSERT_NOT_REACHED(); 270 ASSERT_NOT_REACHED();
274 return true; 271 return true;
275 }; 272 };
276 273
277 String message = String::format( 274 logToConsole(frame, url, resourceRequest.requestContext(), allowed);
278 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested an insecure %s '%s'. %s",
279 frame->document()->url().elidedString().utf8().data(), typeNameFromConte xt(requestContext), url.elidedString().utf8().data(),
280 allowed ? "This content should also be served over HTTPS." : "This reque st has been blocked; the content must be served over HTTPS.");
281 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve l;
282 frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageS ource, messageLevel, message));
283
284 return !allowed; 275 return !allowed;
285 } 276 }
286 277
287 // static 278 bool MixedContentChecker::canDisplayInsecureContentInternal(SecurityOrigin* secu rityOrigin, const KURL& url, const MixedContentType type) const
288 bool MixedContentChecker::shouldBlockWebSocket(LocalFrame* frame, const KURL& ur l)
289 { 279 {
290 // FIXME: Should we have a RequestContext for WebSockets? Probably not, but this feels hacky otherwise. 280 // Check the top frame if it differs from MixedContentChecker's m_frame.
291 LocalFrame* effectiveFrame = inWhichFrameIsThisContentMixed(frame, WebURLReq uest::RequestContextXMLHttpRequest, WebURLRequest::FrameTypeNone, url); 281 if (!m_frame->tree().top()->isLocalFrame()) {
292 if (!effectiveFrame) 282 // FIXME: We need a way to access the top-level frame's MixedContentChec ker when that frame
283 // is in a different process from the current frame. Until that is done, we always allow
284 // loads in remote frames.
285 return false;
286 }
287 Frame* top = m_frame->tree().top();
288 if (top != m_frame && !toLocalFrame(top)->loader().mixedContentChecker()->ca nDisplayInsecureContent(toLocalFrame(top)->document()->securityOrigin(), url))
293 return false; 289 return false;
294 290
295 Settings* settings = effectiveFrame->settings(); 291 // Just count these for the moment, don't block them.
296 FrameLoaderClient* client = effectiveFrame->loader().client(); 292 if (Platform::current()->isReservedIPAddress(url) && !Platform::current()->i sReservedIPAddress(KURL(ParsedURLString, securityOrigin->toString())))
297 SecurityOrigin* securityOrigin = effectiveFrame->document()->securityOrigin( ); 293 UseCounter::count(m_frame->document(), UseCounter::MixedContentPrivateIP InPublicWebsitePassive);
298 bool allowed = false;
299 294
300 if (RuntimeEnabledFeatures::laxMixedContentCheckingEnabled()) { 295 // Then check the current frame:
301 allowed = client->allowDisplayingInsecureContent(settings && (settings-> allowRunningOfInsecureContent() || settings->allowConnectingInsecureWebSocket()) , securityOrigin, url); 296 if (!isMixedContent(securityOrigin, url))
302 if (allowed) 297 return true;
303 client->didDisplayInsecureContent();
304 } else {
305 allowed = client->allowRunningInsecureContent(settings && (settings->all owRunningOfInsecureContent() || settings->allowConnectingInsecureWebSocket()), s ecurityOrigin, url);
306 if (allowed)
307 client->didRunInsecureContent(securityOrigin, url);
308 }
309 298
310 String message = String::format( 299 Settings* settings = m_frame->settings();
311 "Mixed Content: The page at '%s' was loaded over HTTPS, but requested th e WebSocket endpoint '%s'. %s", 300 bool allowed = client()->allowDisplayingInsecureContent(settings && settings ->allowDisplayOfInsecureContent(), securityOrigin, url);
312 effectiveFrame->document()->url().elidedString().utf8().data(), url.elid edString().utf8().data(), 301 logWarning(allowed, url, type);
313 allowed ? "This endpoint should also be secure ('wss:')." : "This reques t has been blocked; the endpoint must be secure ('wss:').");
314 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve l;
315 effectiveFrame->document()->addConsoleMessage(ConsoleMessage::create(Securit yMessageSource, messageLevel, message));
316 302
317 return !allowed; 303 if (allowed)
304 client()->didDisplayInsecureContent();
305
306 return allowed;
318 } 307 }
319 308
320 // static 309 bool MixedContentChecker::canRunInsecureContentInternal(SecurityOrigin* security Origin, const KURL& url, const MixedContentType type) const
321 bool MixedContentChecker::checkFormAction(LocalFrame* frame, const KURL& url) 310 {
311 // Check the top frame if it differs from MixedContentChecker's m_frame.
312 if (!m_frame->tree().top()->isLocalFrame()) {
313 // FIXME: We need a way to access the top-level frame's MixedContentChec ker when that frame
314 // is in a different process from the current frame. Until that is done, we always allow
315 // loads in remote frames.
316 return true;
317 }
318 Frame* top = m_frame->tree().top();
319 if (top != m_frame && !toLocalFrame(top)->loader().mixedContentChecker()->ca nRunInsecureContent(toLocalFrame(top)->document()->securityOrigin(), url))
320 return false;
321
322 // Just count these for the moment, don't block them.
323 if (Platform::current()->isReservedIPAddress(url) && !Platform::current()->i sReservedIPAddress(KURL(ParsedURLString, securityOrigin->toString())))
324 UseCounter::count(m_frame->document(), UseCounter::MixedContentPrivateIP InPublicWebsiteActive);
325
326 // Then check the current frame:
327 if (!isMixedContent(securityOrigin, url))
328 return true;
329
330 Settings* settings = m_frame->settings();
331 bool allowedPerSettings = settings && (settings->allowRunningOfInsecureConte nt() || ((type == WebSocket) && settings->allowConnectingInsecureWebSocket()));
332 bool allowed = client()->allowRunningInsecureContent(allowedPerSettings, sec urityOrigin, url);
333 logWarning(allowed, url, type);
334
335 if (allowed)
336 client()->didRunInsecureContent(securityOrigin, url);
337
338 return allowed;
339 }
340
341 bool MixedContentChecker::canFrameInsecureContent(SecurityOrigin* securityOrigin , const KURL& url) const
342 {
343 // If we're dealing with a CORS-enabled scheme, then block mixed frames as a ctive content. Otherwise,
344 // treat frames as passive content.
345 //
346 // FIXME: Remove this temporary hack once we have a reasonable API for launc hing external applications
347 // via URLs. http://crbug.com/318788 and https://crbug.com/393481
348 if (SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(url.protocol()))
349 return canRunInsecureContentInternal(securityOrigin, url, MixedContentCh ecker::Execution);
350 return canDisplayInsecureContentInternal(securityOrigin, url, MixedContentCh ecker::Display);
351 }
352
353 bool MixedContentChecker::canConnectInsecureWebSocket(SecurityOrigin* securityOr igin, const KURL& url) const
354 {
355 if (RuntimeEnabledFeatures::laxMixedContentCheckingEnabled())
356 return canDisplayInsecureContentInternal(securityOrigin, url, MixedConte ntChecker::WebSocket);
357 return canRunInsecureContentInternal(securityOrigin, url, MixedContentChecke r::WebSocket);
358 }
359
360 bool MixedContentChecker::canSubmitToInsecureForm(SecurityOrigin* securityOrigin , const KURL& url) const
322 { 361 {
323 // For whatever reason, some folks handle forms via JavaScript, and submit t o `javascript:void(0)` 362 // For whatever reason, some folks handle forms via JavaScript, and submit t o `javascript:void(0)`
324 // rather than calling `preventDefault()`. We special-case `javascript:` URL s here, as they don't 363 // rather than calling `preventDefault()`. We special-case `javascript:` URL s here, as they don't
325 // introduce MixedContent for form submissions. 364 // introduce MixedContent for form submissions.
326 if (url.protocolIs("javascript")) 365 if (url.protocolIs("javascript"))
327 return false; 366 return true;
328 367
329 // If lax mixed content checking is enabled (noooo!), skip this check entire ly. 368 // If lax mixed content checking is enabled (noooo!), skip this check entire ly.
330 if (RuntimeEnabledFeatures::laxMixedContentCheckingEnabled()) 369 if (RuntimeEnabledFeatures::laxMixedContentCheckingEnabled())
331 return false; 370 return true;
371 return canDisplayInsecureContentInternal(securityOrigin, url, MixedContentCh ecker::Submission);
372 }
332 373
333 LocalFrame* effectiveFrame = inWhichFrameIsThisContentMixed(frame, WebURLReq uest::RequestContextForm, WebURLRequest::FrameTypeNone, url); 374 void MixedContentChecker::logWarning(bool allowed, const KURL& target, const Mix edContentType type) const
334 if (!effectiveFrame) 375 {
335 return false; 376 StringBuilder message;
336 377 message.append((allowed ? "" : "[blocked] "));
337 // No "allowed" check here; we're not yet exposing anything which would bloc k form submission. 378 message.append("The page at '" + m_frame->document()->url().elidedString() + "' was loaded over HTTPS, but ");
338 FrameLoaderClient* client = effectiveFrame->loader().client(); 379 switch (type) {
339 client->didDisplayInsecureContent(); 380 case Display:
340 381 message.append("displayed insecure content from '" + target.elidedString () + "': this content should also be loaded over HTTPS.\n");
341 String message = String::format( 382 break;
342 "Mixed Content: The page at '%s' was loaded over HTTPS, but contains a f orm whose 'action' attribute is '%s'. This form should not submit data to insecu re endpoints.", 383 case Execution:
343 effectiveFrame->document()->url().elidedString().utf8().data(), url.elid edString().utf8().data()); 384 case WebSocket:
344 effectiveFrame->document()->addConsoleMessage(ConsoleMessage::create(Securit yMessageSource, WarningMessageLevel, message)); 385 message.append("ran insecure content from '" + target.elidedString() + " ': this content should also be loaded over HTTPS.\n");
345 return true; 386 break;
387 case Submission:
388 message.append("is submitting data to an insecure location at '" + targe t.elidedString() + "': this content should also be submitted over HTTPS.\n");
389 break;
390 }
391 MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLeve l;
392 m_frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessag eSource, messageLevel, message.toString()));
346 } 393 }
347 394
348 void MixedContentChecker::checkMixedPrivatePublic(LocalFrame* frame, const Atomi cString& resourceIPAddress) 395 void MixedContentChecker::checkMixedPrivatePublic(LocalFrame* frame, const Atomi cString& resourceIPAddress)
349 { 396 {
350 if (!frame || !frame->document() || !frame->document()->loader()) 397 if (!frame || !frame->document() || !frame->document()->loader())
351 return; 398 return;
352 399
353 KURL documentIP(ParsedURLString, "http://" + frame->document()->loader()->re sponse().remoteIPAddress()); 400 KURL documentIP(ParsedURLString, "http://" + frame->document()->loader()->re sponse().remoteIPAddress());
354 KURL resourceIP(ParsedURLString, "http://" + resourceIPAddress); 401 KURL resourceIP(ParsedURLString, "http://" + resourceIPAddress);
355 402
356 // Just count these for the moment, don't block them. 403 // Just count these for the moment, don't block them.
357 // 404 //
358 // FIXME: Once we know how we want to check this, adjust the platform APIs t o avoid the KURL construction. 405 // FIXME: Once we know how we want to check this, adjust the platform APIs t o avoid the KURL construction.
359 if (Platform::current()->isReservedIPAddress(resourceIP) && !Platform::curre nt()->isReservedIPAddress(documentIP)) 406 if (Platform::current()->isReservedIPAddress(resourceIP) && !Platform::curre nt()->isReservedIPAddress(documentIP))
360 UseCounter::count(frame->document(), UseCounter::MixedContentPrivateHost nameInPublicHostname); 407 UseCounter::count(frame->document(), UseCounter::MixedContentPrivateHost nameInPublicHostname);
361 } 408 }
362 409
363 } // namespace blink 410 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/loader/MixedContentChecker.h ('k') | Source/core/loader/PingLoader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698