1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
content / browser / web_contents / web_contents_view_drag_security_info.cc [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/web_contents/web_contents_view_drag_security_info.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/site_instance_group.h"
#include "content/public/common/drop_data.h"
namespace content {
WebContentsViewDragSecurityInfo::WebContentsViewDragSecurityInfo() = default;
WebContentsViewDragSecurityInfo::~WebContentsViewDragSecurityInfo() = default;
void WebContentsViewDragSecurityInfo::OnDragInitiated(
RenderWidgetHostImpl* source_rwh,
const DropData& drop_data) {
did_initiate_ = true;
site_instance_group_id_ = source_rwh->GetSiteInstanceGroup()->GetId();
image_accessible_from_frame_ = drop_data.file_contents_image_accessible;
}
void WebContentsViewDragSecurityInfo::OnDragEnded() {
did_initiate_ = false;
site_instance_group_id_ = SiteInstanceGroupId();
image_accessible_from_frame_ = true;
}
bool WebContentsViewDragSecurityInfo::IsImageAccessibleFromFrame() const {
// `is_initiated_` is false when the drag started outside of the browser or
// from a different top-level WebContents. The drag is allowed if that is the
// case.
if (!did_initiate_) {
return true;
}
return image_accessible_from_frame_;
}
// The browser-side check for https://crbug.com/59081 to block drags between
// cross-origin frames within the same page. Otherwise, a malicious attacker
// could abuse drag interactions to leak information across origins without
// explicit user intent.
bool WebContentsViewDragSecurityInfo::IsValidDragTarget(
RenderWidgetHostImpl* target_rwh) const {
// `is_initiated_` is false when the drag started outside of the browser or
// from a different top-level WebContents. The drag is allowed if that is the
// case.
if (!did_initiate_) {
return true;
}
// For site isolation, it is desirable to avoid having the renderer
// perform the check unless it already has access to the starting
// document's origin. If the SiteInstanceGroups match, then the process
// allocation policy decided that it is OK for the source and target
// frames to live in the same renderer process. Furthermore, having matching
// SiteInstanceGroups means that either (1) the source and target frame are
// part of the same blink::Page, or (2) that they are in the same Browsing
// Context Group and the drag would cross tab boundaries (the latter of which
// can't happen here since `is_initiated_` is true). Allow this drag to
// the renderer. Blink will perform an additional check against
// `blink::DragController::drag_initiator_` to decide whether or not to
// allow the drag operation. This can be done in the renderer, as the
// browser-side checks only have local tree fragment (potentially with
// multiple origins) granularity at best, but a drag operation eventually
// targets one single frame in that local tree fragment.
return target_rwh->GetSiteInstanceGroup()->GetId() == site_instance_group_id_;
}
} // namespace content