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

Side by Side Diff: content/browser/web_contents/web_drag_dest_gtk.cc

Issue 207013003: Mark drags starting in web content as tainted to avoid file path forgery (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More fixes and comment Created 6 years, 9 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/web_contents/web_drag_dest_gtk.h" 5 #include "content/browser/web_contents/web_drag_dest_gtk.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 return modifier_state; 46 return modifier_state;
47 } 47 }
48 48
49 } // namespace 49 } // namespace
50 50
51 WebDragDestGtk::WebDragDestGtk(WebContents* web_contents, GtkWidget* widget) 51 WebDragDestGtk::WebDragDestGtk(WebContents* web_contents, GtkWidget* widget)
52 : web_contents_(web_contents), 52 : web_contents_(web_contents),
53 widget_(widget), 53 widget_(widget),
54 context_(NULL), 54 context_(NULL),
55 data_requests_(0), 55 data_requests_(0),
56 renderer_tainted_(false),
56 delegate_(NULL), 57 delegate_(NULL),
57 canceled_(false), 58 canceled_(false),
58 method_factory_(this) { 59 method_factory_(this) {
59 gtk_drag_dest_set(widget, static_cast<GtkDestDefaults>(0), 60 gtk_drag_dest_set(widget, static_cast<GtkDestDefaults>(0),
60 NULL, 0, 61 NULL, 0,
61 static_cast<GdkDragAction>(GDK_ACTION_COPY | 62 static_cast<GdkDragAction>(GDK_ACTION_COPY |
62 GDK_ACTION_LINK | 63 GDK_ACTION_LINK |
63 GDK_ACTION_MOVE)); 64 GDK_ACTION_MOVE));
64 65
65 // If adding a handler, make sure to update kNumGtkHandlers and add it to the 66 // If adding a handler, make sure to update kNumGtkHandlers and add it to the
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 is_drop_target_ = false; 115 is_drop_target_ = false;
115 116
116 if (delegate()) 117 if (delegate())
117 delegate()->DragInitialize(web_contents_); 118 delegate()->DragInitialize(web_contents_);
118 119
119 // text/plain must come before text/uri-list. This is a hack that works in 120 // text/plain must come before text/uri-list. This is a hack that works in
120 // conjunction with OnDragDataReceived. Since some file managers populate 121 // conjunction with OnDragDataReceived. Since some file managers populate
121 // text/plain with file URLs when dragging files, we want to handle 122 // text/plain with file URLs when dragging files, we want to handle
122 // text/uri-list after text/plain so that the plain text can be cleared if 123 // text/uri-list after text/plain so that the plain text can be cleared if
123 // it's a file drag. 124 // it's a file drag.
125 // Similarly, renderer taint must occur before anything else so we can
126 // ignore potentially forged filenames when handling text/uri-list.
124 static int supported_targets[] = { 127 static int supported_targets[] = {
128 ui::RENDERER_TAINT,
125 ui::TEXT_PLAIN, 129 ui::TEXT_PLAIN,
126 ui::TEXT_URI_LIST, 130 ui::TEXT_URI_LIST,
127 ui::TEXT_HTML, 131 ui::TEXT_HTML,
128 ui::NETSCAPE_URL, 132 ui::NETSCAPE_URL,
129 ui::CHROME_NAMED_URL, 133 ui::CHROME_NAMED_URL,
130 // TODO(estade): support image drags? 134 // TODO(estade): support image drags?
131 ui::CUSTOM_DATA, 135 ui::CUSTOM_DATA,
132 }; 136 };
133 137
138 renderer_tainted_ = false;
134 // Add the delegate's requested target if applicable. Need to do this here 139 // Add the delegate's requested target if applicable. Need to do this here
135 // since gtk_drag_get_data will dispatch to our drag-data-received. 140 // since gtk_drag_get_data will dispatch to our drag-data-received.
136 data_requests_ = arraysize(supported_targets) + (delegate() ? 1 : 0); 141 data_requests_ = arraysize(supported_targets) + (delegate() ? 1 : 0);
137 for (size_t i = 0; i < arraysize(supported_targets); ++i) { 142 for (size_t i = 0; i < arraysize(supported_targets); ++i) {
138 gtk_drag_get_data(widget_, context, 143 gtk_drag_get_data(widget_, context,
139 ui::GetAtomForTarget(supported_targets[i]), 144 ui::GetAtomForTarget(supported_targets[i]),
140 time); 145 time);
141 } 146 }
142 147
143 if (delegate()) { 148 if (delegate()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 180
176 data_requests_--; 181 data_requests_--;
177 182
178 // Decode the data. 183 // Decode the data.
179 gint data_length = gtk_selection_data_get_length(data); 184 gint data_length = gtk_selection_data_get_length(data);
180 const guchar* raw_data = gtk_selection_data_get_data(data); 185 const guchar* raw_data = gtk_selection_data_get_data(data);
181 GdkAtom target = gtk_selection_data_get_target(data); 186 GdkAtom target = gtk_selection_data_get_target(data);
182 if (raw_data && data_length > 0) { 187 if (raw_data && data_length > 0) {
183 // If the source can't provide us with valid data for a requested target, 188 // If the source can't provide us with valid data for a requested target,
184 // raw_data will be NULL. 189 // raw_data will be NULL.
185 if (target == ui::GetAtomForTarget(ui::TEXT_PLAIN)) { 190 if (target == ui::GetAtomForTarget(ui::RENDERER_TAINT)) {
191 renderer_tainted_ = true;
192 } else if (target == ui::GetAtomForTarget(ui::TEXT_PLAIN)) {
186 guchar* text = gtk_selection_data_get_text(data); 193 guchar* text = gtk_selection_data_get_text(data);
187 if (text) { 194 if (text) {
188 drop_data_->text = base::NullableString16( 195 drop_data_->text = base::NullableString16(
189 base::UTF8ToUTF16(std::string(reinterpret_cast<const char*>(text))), 196 base::UTF8ToUTF16(std::string(reinterpret_cast<const char*>(text))),
190 false); 197 false);
191 g_free(text); 198 g_free(text);
192 } 199 }
193 } else if (target == ui::GetAtomForTarget(ui::TEXT_URI_LIST)) { 200 } else if (target == ui::GetAtomForTarget(ui::TEXT_URI_LIST)) {
194 gchar** uris = gtk_selection_data_get_uris(data); 201 gchar** uris = gtk_selection_data_get_uris(data);
195 if (uris) { 202 if (uris) {
196 drop_data_->url = GURL(); 203 drop_data_->url = GURL();
197 for (gchar** uri_iter = uris; *uri_iter; uri_iter++) { 204 for (gchar** uri_iter = uris; *uri_iter; uri_iter++) {
198 // Most file managers populate text/uri-list with file URLs when 205 // Most file managers populate text/uri-list with file URLs when
199 // dragging files. To avoid exposing file system paths to web content, 206 // dragging files. To avoid exposing file system paths to web content,
200 // file URLs are never set as the URL content for the drop. 207 // file URLs are never set as the URL content for the drop.
201 // TODO(estade): Can the filenames have a non-UTF8 encoding? 208 // TODO(estade): Can the filenames have a non-UTF8 encoding?
202 GURL url(*uri_iter); 209 GURL url(*uri_iter);
203 base::FilePath file_path; 210 base::FilePath file_path;
204 if (url.SchemeIs(kFileScheme) && 211 if (!renderer_tainted_ &&
212 url.SchemeIs(kFileScheme) &&
205 net::FileURLToFilePath(url, &file_path)) { 213 net::FileURLToFilePath(url, &file_path)) {
206 drop_data_->filenames.push_back( 214 drop_data_->filenames.push_back(DropData::FileInfo(
207 DropData::FileInfo(base::UTF8ToUTF16(file_path.value()), 215 base::UTF8ToUTF16(file_path.value()), base::string16()));
208 base::string16()));
209 // This is a hack. Some file managers also populate text/plain with 216 // This is a hack. Some file managers also populate text/plain with
210 // a file URL when dragging files, so we clear it to avoid exposing 217 // a file URL when dragging files, so we clear it to avoid exposing
211 // it to the web content. 218 // it to the web content.
212 drop_data_->text = base::NullableString16(); 219 drop_data_->text = base::NullableString16();
213 } else if (!drop_data_->url.is_valid()) { 220 } else if (!drop_data_->url.is_valid()) {
214 // Also set the first non-file URL as the URL content for the drop. 221 // Also set the first non-file URL as the URL content for the drop.
215 drop_data_->url = url; 222 drop_data_->url = url;
216 } 223 }
217 } 224 }
218 g_strfreev(uris); 225 g_strfreev(uris);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 gtk_drag_finish(context, is_drop_target_, FALSE, time); 339 gtk_drag_finish(context, is_drop_target_, FALSE, time);
333 340
334 return TRUE; 341 return TRUE;
335 } 342 }
336 343
337 RenderViewHostImpl* WebDragDestGtk::GetRenderViewHost() const { 344 RenderViewHostImpl* WebDragDestGtk::GetRenderViewHost() const {
338 return static_cast<RenderViewHostImpl*>(web_contents_->GetRenderViewHost()); 345 return static_cast<RenderViewHostImpl*>(web_contents_->GetRenderViewHost());
339 } 346 }
340 347
341 } // namespace content 348 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698