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

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

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