Commit 0678253f authored by paulmeyer's avatar paulmeyer Committed by Commit bot

Prevent drag-and-drop events from firing over cross-site, same-page

frames.

This is a follow-up to https://codereview.chromium.org/2568893002/,
enabling the same behavior on Mac.

Review-Url: https://codereview.chromium.org/2580843003
Cr-Commit-Position: refs/heads/master@{#438911}
parent 08525f40
...@@ -549,6 +549,7 @@ void WebContentsViewMac::CloseTab() { ...@@ -549,6 +549,7 @@ void WebContentsViewMac::CloseTab() {
offset:(NSPoint)offset { offset:(NSPoint)offset {
if (![self webContents]) if (![self webContents])
return; return;
[dragDest_ setDragStartTrackersForProcess:sourceRWH->GetProcess()->GetID()];
dragSource_.reset([[WebDragSource alloc] dragSource_.reset([[WebDragSource alloc]
initWithContents:[self webContents] initWithContents:[self webContents]
view:self view:self
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "content/browser/loader/global_routing_id.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/public/common/drop_data.h" #include "content/public/common/drop_data.h"
#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point.h"
...@@ -44,6 +45,15 @@ CONTENT_EXPORT ...@@ -44,6 +45,15 @@ CONTENT_EXPORT
// during a drag, we need to re-send the DragEnter message. // during a drag, we need to re-send the DragEnter message.
RenderViewHostIdentifier currentRVH_; RenderViewHostIdentifier currentRVH_;
// Tracks the IDs of the source RenderProcessHost and RenderViewHost from
// which the current drag originated. These are set in
// -setDragStartTrackersForProcess:, and are used to ensure that drag events
// do not fire over a cross-site frame (with respect to the source frame) in
// the same page (see crbug.com/666858). See
// WebContentsViewAura::drag_start_process_id_ for additional information.
int dragStartProcessID_;
content::GlobalRoutingID dragStartViewID_;
// The data for the current drag, or NULL if none is in progress. // The data for the current drag, or NULL if none is in progress.
std::unique_ptr<content::DropData> dropData_; std::unique_ptr<content::DropData> dropData_;
...@@ -79,6 +89,14 @@ CONTENT_EXPORT ...@@ -79,6 +89,14 @@ CONTENT_EXPORT
GetRenderWidgetHostAtPoint:(const NSPoint&)viewPoint GetRenderWidgetHostAtPoint:(const NSPoint&)viewPoint
transformedPt:(gfx::Point*)transformedPt; transformedPt:(gfx::Point*)transformedPt;
// Sets |dragStartProcessID_| and |dragStartViewID_|.
- (void)setDragStartTrackersForProcess:(int)processID;
// Returns whether |targetRWH| is a valid RenderWidgetHost to be dragging
// over. This enforces that same-page, cross-site drags are not allowed. See
// crbug.com/666858.
- (bool)isValidDragTarget:(content::RenderWidgetHostImpl*)targetRWH;
@end @end
// Public use only for unit tests. // Public use only for unit tests.
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_drag_dest_delegate.h" #include "content/public/browser/web_drag_dest_delegate.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/drop_data.h" #include "content/public/common/drop_data.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h" #include "third_party/WebKit/public/platform/WebInputEvent.h"
#import "third_party/mozilla/NSPasteboard+Utils.h" #import "third_party/mozilla/NSPasteboard+Utils.h"
...@@ -57,6 +58,11 @@ int GetModifierFlags() { ...@@ -57,6 +58,11 @@ int GetModifierFlags() {
return modifier_state; return modifier_state;
} }
content::GlobalRoutingID GetRenderViewHostID(content::RenderViewHost* rvh) {
return content::GlobalRoutingID(rvh->GetProcess()->GetID(),
rvh->GetRoutingID());
}
} // namespace } // namespace
@implementation WebDragDest @implementation WebDragDest
...@@ -68,6 +74,9 @@ int GetModifierFlags() { ...@@ -68,6 +74,9 @@ int GetModifierFlags() {
if ((self = [super init])) { if ((self = [super init])) {
webContents_ = contents; webContents_ = contents;
canceled_ = false; canceled_ = false;
dragStartProcessID_ = content::ChildProcessHost::kInvalidUniqueID;
dragStartViewID_ = content::GlobalRoutingID(
content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
} }
return self; return self;
} }
...@@ -141,9 +150,13 @@ int GetModifierFlags() { ...@@ -141,9 +150,13 @@ int GetModifierFlags() {
canceled_ = true; canceled_ = true;
return NSDragOperationNone; return NSDragOperationNone;
} }
currentRWHForDrag_ =
[self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt] content::RenderWidgetHostImpl* targetRWH =
->GetWeakPtr(); [self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt];
if (![self isValidDragTarget:targetRWH])
return NSDragOperationNone;
currentRWHForDrag_ = targetRWH->GetWeakPtr();
// Fill out a DropData from pasteboard. // Fill out a DropData from pasteboard.
std::unique_ptr<DropData> dropData; std::unique_ptr<DropData> dropData;
...@@ -224,6 +237,9 @@ int GetModifierFlags() { ...@@ -224,6 +237,9 @@ int GetModifierFlags() {
content::RenderWidgetHostImpl* targetRWH = content::RenderWidgetHostImpl* targetRWH =
[self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt]; [self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt];
if (![self isValidDragTarget:targetRWH])
return NSDragOperationNone;
// TODO(paulmeyer): The dragging delegates may now by invoked multiple times // TODO(paulmeyer): The dragging delegates may now by invoked multiple times
// per drag, even without the drag ever leaving the window. // per drag, even without the drag ever leaving the window.
if (targetRWH != currentRWHForDrag_.get()) { if (targetRWH != currentRWHForDrag_.get()) {
...@@ -263,6 +279,9 @@ int GetModifierFlags() { ...@@ -263,6 +279,9 @@ int GetModifierFlags() {
content::RenderWidgetHostImpl* targetRWH = content::RenderWidgetHostImpl* targetRWH =
[self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt]; [self GetRenderWidgetHostAtPoint:viewPoint transformedPt:&transformedPt];
if (![self isValidDragTarget:targetRWH])
return NO;
if (targetRWH != currentRWHForDrag_.get()) { if (targetRWH != currentRWHForDrag_.get()) {
if (currentRWHForDrag_) if (currentRWHForDrag_)
currentRWHForDrag_->DragTargetDragLeave(); currentRWHForDrag_->DragTargetDragLeave();
...@@ -306,6 +325,17 @@ GetRenderWidgetHostAtPoint:(const NSPoint&)viewPoint ...@@ -306,6 +325,17 @@ GetRenderWidgetHostAtPoint:(const NSPoint&)viewPoint
gfx::Point(viewPoint.x, viewPoint.y), transformedPt); gfx::Point(viewPoint.x, viewPoint.y), transformedPt);
} }
- (void)setDragStartTrackersForProcess:(int)processID {
dragStartProcessID_ = processID;
dragStartViewID_ = GetRenderViewHostID(webContents_->GetRenderViewHost());
}
- (bool)isValidDragTarget:(content::RenderWidgetHostImpl*)targetRWH {
return targetRWH->GetProcess()->GetID() == dragStartProcessID_ ||
GetRenderViewHostID(webContents_->GetRenderViewHost()) !=
dragStartViewID_;
}
// Given |data|, which should not be nil, fill it in using the contents of the // Given |data|, which should not be nil, fill it in using the contents of the
// given pasteboard. The types handled by this method should be kept in sync // given pasteboard. The types handled by this method should be kept in sync
// with [WebContentsViewCocoa registerDragTypes]. // with [WebContentsViewCocoa registerDragTypes].
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment