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

Side by Side Diff: chrome/browser/external_protocol_handler.cc

Issue 240002: Hook up external protocol handler to user gestures to prevent malicious sites... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 2 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
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/external_protocol_handler.h" 5 #include "chrome/browser/external_protocol_handler.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #include <set> 9 #include <set>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/thread.h" 14 #include "base/thread.h"
15 #include "chrome/browser/browser.h" 15 #include "chrome/browser/browser.h"
16 #include "chrome/browser/browser_process_impl.h" 16 #include "chrome/browser/browser_process_impl.h"
17 #include "chrome/common/platform_util.h" 17 #include "chrome/common/platform_util.h"
18 #include "chrome/common/pref_service.h" 18 #include "chrome/common/pref_service.h"
19 #include "chrome/common/pref_names.h" 19 #include "chrome/common/pref_names.h"
20 #include "googleurl/src/gurl.h" 20 #include "googleurl/src/gurl.h"
21 #include "net/base/escape.h" 21 #include "net/base/escape.h"
22 22
23 // Whether we accept requests for launching external protocols. This is set to
24 // false every time an external protocol is requested, and set back to true on
25 // each user gesture. This variable should only be accessed from the UI thread.
26 static bool g_accept_requests = true;
27
23 // static 28 // static
24 void ExternalProtocolHandler::PrepopulateDictionary(DictionaryValue* win_pref) { 29 void ExternalProtocolHandler::PrepopulateDictionary(DictionaryValue* win_pref) {
25 static bool is_warm = false; 30 static bool is_warm = false;
26 if (is_warm) 31 if (is_warm)
27 return; 32 return;
28 is_warm = true; 33 is_warm = true;
29 34
30 static const wchar_t* const denied_schemes[] = { 35 static const wchar_t* const denied_schemes[] = {
31 L"afp", 36 L"afp",
32 L"data", 37 L"data",
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 for (size_t i = 0; i < arraysize(allowed_schemes); ++i) { 71 for (size_t i = 0; i < arraysize(allowed_schemes); ++i) {
67 if (!win_pref->GetBoolean(allowed_schemes[i], &should_block)) { 72 if (!win_pref->GetBoolean(allowed_schemes[i], &should_block)) {
68 win_pref->SetBoolean(allowed_schemes[i], false); 73 win_pref->SetBoolean(allowed_schemes[i], false);
69 } 74 }
70 } 75 }
71 } 76 }
72 77
73 // static 78 // static
74 ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState( 79 ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState(
75 const std::wstring& scheme) { 80 const std::wstring& scheme) {
81 // If we are being carpet bombed, block the request.
82 if (!g_accept_requests)
83 return BLOCK;
84
76 if (scheme.length() == 1) { 85 if (scheme.length() == 1) {
77 // We have a URL that looks something like: 86 // We have a URL that looks something like:
78 // C:/WINDOWS/system32/notepad.exe 87 // C:/WINDOWS/system32/notepad.exe
79 // ShellExecuting this URL will cause the specified program to be executed. 88 // ShellExecuting this URL will cause the specified program to be executed.
80 return BLOCK; 89 return BLOCK;
81 } 90 }
82 91
83 // Check the stored prefs. 92 // Check the stored prefs.
84 // TODO(pkasting): http://b/119651 This kind of thing should go in the 93 // TODO(pkasting): http://b/119651 This kind of thing should go in the
85 // preferences on the profile, not in the local state. 94 // preferences on the profile, not in the local state.
(...skipping 11 matching lines...) Expand all
97 return should_block ? BLOCK : DONT_BLOCK; 106 return should_block ? BLOCK : DONT_BLOCK;
98 } 107 }
99 108
100 return UNKNOWN; 109 return UNKNOWN;
101 } 110 }
102 111
103 // static 112 // static
104 void ExternalProtocolHandler::LaunchUrl(const GURL& url, 113 void ExternalProtocolHandler::LaunchUrl(const GURL& url,
105 int render_process_host_id, 114 int render_process_host_id,
106 int tab_contents_id) { 115 int tab_contents_id) {
116 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());
117
107 // Escape the input scheme to be sure that the command does not 118 // Escape the input scheme to be sure that the command does not
108 // have parameters unexpected by the external program. 119 // have parameters unexpected by the external program.
109 std::string escaped_url_string = EscapeExternalHandlerValue(url.spec()); 120 std::string escaped_url_string = EscapeExternalHandlerValue(url.spec());
110 GURL escaped_url(escaped_url_string); 121 GURL escaped_url(escaped_url_string);
111 BlockState block_state = GetBlockState(ASCIIToWide(escaped_url.scheme())); 122 BlockState block_state = GetBlockState(ASCIIToWide(escaped_url.scheme()));
112 if (block_state == BLOCK) 123 if (block_state == BLOCK)
113 return; 124 return;
114 125
115 if (block_state == UNKNOWN) { 126 if (block_state == UNKNOWN) {
116 #if defined(OS_WIN) || defined(TOOLKIT_GTK) 127 #if defined(OS_WIN) || defined(TOOLKIT_GTK)
128 g_accept_requests = false;
117 // Ask the user if they want to allow the protocol. This will call 129 // Ask the user if they want to allow the protocol. This will call
118 // LaunchUrlWithoutSecurityCheck if the user decides to accept the protocol. 130 // LaunchUrlWithoutSecurityCheck if the user decides to accept the protocol.
119 RunExternalProtocolDialog(escaped_url, 131 RunExternalProtocolDialog(escaped_url,
120 render_process_host_id, 132 render_process_host_id,
121 tab_contents_id); 133 tab_contents_id);
122 #endif 134 #endif
123 // For now, allow only whitelisted protocols to fire on Mac and Linux/Views. 135 // For now, allow only whitelisted protocols to fire on Mac and Linux/Views.
124 // See http://crbug.com/15546. 136 // See http://crbug.com/15546.
125 return; 137 return;
126 } 138 }
127 139
128 LaunchUrlWithoutSecurityCheck(escaped_url); 140 LaunchUrlWithoutSecurityCheck(escaped_url);
129 } 141 }
130 142
131 // static 143 // static
132 void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(const GURL& url) { 144 void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(const GURL& url) {
133 #if defined(OS_MACOSX) 145 #if defined(OS_MACOSX)
134 // This must run on the main thread on OS X. 146 // This must run on the UI thread on OS X.
135 platform_util::OpenExternal(url); 147 platform_util::OpenExternal(url);
136 #else 148 #else
137 // Otherwise put this work on the file thread. On Windows ShellExecute may 149 // Otherwise put this work on the file thread. On Windows ShellExecute may
138 // block for a significant amount of time, and it shouldn't hurt on Linux. 150 // block for a significant amount of time, and it shouldn't hurt on Linux.
139 MessageLoop* loop = g_browser_process->file_thread()->message_loop(); 151 MessageLoop* loop = g_browser_process->file_thread()->message_loop();
140 if (loop == NULL) { 152 if (loop == NULL) {
141 return; 153 return;
142 } 154 }
143 155
144 loop->PostTask(FROM_HERE, 156 loop->PostTask(FROM_HERE,
145 NewRunnableFunction(&platform_util::OpenExternal, url)); 157 NewRunnableFunction(&platform_util::OpenExternal, url));
146 #endif 158 #endif
147 } 159 }
148 160
149 // static 161 // static
150 void ExternalProtocolHandler::RegisterPrefs(PrefService* prefs) { 162 void ExternalProtocolHandler::RegisterPrefs(PrefService* prefs) {
151 prefs->RegisterDictionaryPref(prefs::kExcludedSchemes); 163 prefs->RegisterDictionaryPref(prefs::kExcludedSchemes);
152 } 164 }
165
166 // static
167 void ExternalProtocolHandler::OnUserGesture() {
168 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());
169 g_accept_requests = true;
170 }
OLDNEW
« no previous file with comments | « chrome/browser/external_protocol_handler.h ('k') | chrome/browser/gtk/external_protocol_dialog_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698