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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_CHILD_SITE_ISOLATION_POLICY_H_
#define CONTENT_CHILD_SITE_ISOLATION_POLICY_H_
#include <map>
#include <utility>
#include "base/gtest_prod_util.h"
#include "base/memory/linked_ptr.h"
#include "base/strings/string_piece.h"
#include "content/common/content_export.h"
#include "content/public/common/resource_type.h"
#include "url/gurl.h"
namespace content {
struct ResourceResponseInfo;
// SiteIsolationPolicy implements the cross-site document blocking policy (XSDP)
// for Site Isolation. XSDP will monitor network responses to a renderer and
// block illegal responses so that a compromised renderer cannot steal private
// information from other sites. For now SiteIsolationPolicy monitors responses
// to gather various UMA stats to see the compatibility impact of actual
// deployment of the policy. The UMA stat categories SiteIsolationPolicy gathers
// are as follows:
//
// SiteIsolation.AllResponses : # of all network responses.
// SiteIsolation.XSD.DataLength : the length of the first packet of a response.
// SiteIsolation.XSD.MimeType (enum):
// # of responses from other sites, tagged with a document mime type.
// 0:HTML, 1:XML, 2:JSON, 3:Plain, 4:Others
// SiteIsolation.XSD.[%MIMETYPE].Blocked :
// blocked # of cross-site document responses grouped by sniffed MIME type.
// SiteIsolation.XSD.[%MIMETYPE].Blocked.RenderableStatusCode :
// # of responses with renderable status code,
// out of SiteIsolation.XSD.[%MIMETYPE].Blocked.
// SiteIsolation.XSD.[%MIMETYPE].Blocked.NonRenderableStatusCode :
// # of responses with non-renderable status code,
// out of SiteIsolation.XSD.[%MIMETYPE].Blocked.
// SiteIsolation.XSD.[%MIMETYPE].NoSniffBlocked.RenderableStatusCode :
// # of responses failed to be sniffed for its MIME type, but blocked by
// "X-Content-Type-Options: nosniff" header, and with renderable status code
// out of SiteIsolation.XSD.[%MIMETYPE].Blocked.
// SiteIsolation.XSD.[%MIMETYPE].NoSniffBlocked.NonRenderableStatusCode :
// # of responses failed to be sniffed for its MIME type, but blocked by
// "X-Content-Type-Options: nosniff" header, and with non-renderable status
// code out of SiteIsolation.XSD.[%MIMETYPE].Blocked.
// SiteIsolation.XSD.[%MIMETYPE].NotBlocked :
// # of responses, but not blocked due to failure of mime sniffing.
// SiteIsolation.XSD.[%MIMETYPE].NotBlocked.MaybeJS :
// # of responses that are plausibly sniffed to be JavaScript.
struct SiteIsolationResponseMetaData {
enum CanonicalMimeType {
HTML = 0,
XML = 1,
JSON = 2,
Plain = 3,
Others = 4,
MaxCanonicalMimeType,
};
SiteIsolationResponseMetaData();
std::string frame_origin;
GURL response_url;
ResourceType resource_type;
CanonicalMimeType canonical_mime_type;
int http_status_code;
bool no_sniff;
};
class CONTENT_EXPORT SiteIsolationPolicy {
public:
// Set activation flag for the UMA data collection for this renderer process.
static void SetPolicyEnabled(bool enabled);
// Returns any bookkeeping data about the HTTP header information for the
// request identified by |request_id|. Any data returned should then be
// passed to ShouldBlockResponse with the first packet.
static linked_ptr<SiteIsolationResponseMetaData> OnReceivedResponse(
const GURL& frame_origin,
const GURL& response_url,
ResourceType resource_type,
int origin_pid,
const ResourceResponseInfo& info);
// Examines the first network packet in case response_url is registered as a
// cross-site document by DidReceiveResponse(). In case that this response is
// blocked, it returns an alternative data to be sent to the renderer in
// |alternative_data|. This records various kinds of UMA data stats. This
// function is called only if the length of received data is non-zero.
static bool ShouldBlockResponse(
linked_ptr<SiteIsolationResponseMetaData>& resp_data, const char* payload,
int length, std::string* alternative_data);
private:
FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, IsBlockableScheme);
FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, IsSameSite);
FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, IsValidCorsHeaderSet);
FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, SniffForHTML);
FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, SniffForXML);
FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, SniffForJSON);
FRIEND_TEST_ALL_PREFIXES(SiteIsolationPolicyTest, SniffForJS);
// Returns the representative mime type enum value of the mime type of
// response. For example, this returns the same value for all text/xml mime
// type families such as application/xml, application/rss+xml.
static SiteIsolationResponseMetaData::CanonicalMimeType GetCanonicalMimeType(
const std::string& mime_type);
// Returns whether this scheme is a target of cross-site document
// policy(XSDP). This returns true only for http://* and https://* urls.
static bool IsBlockableScheme(const GURL& frame_origin);
// Returns whether the two urls belong to the same sites.
static bool IsSameSite(const GURL& frame_origin, const GURL& response_url);
// Returns whether there's a valid CORS header for frame_origin. This is
// simliar to CrossOriginAccessControl::passesAccessControlCheck(), but we use
// sites as our security domain, not origins.
// TODO(dsjang): this must be improved to be more accurate to the actual CORS
// specification. For now, this works conservatively, allowing XSDs that are
// not allowed by actual CORS rules by ignoring 1) credentials and 2)
// methods. Preflight requests don't matter here since they are not used to
// decide whether to block a document or not on the client side.
static bool IsValidCorsHeaderSet(const GURL& frame_origin,
const GURL& website_origin,
const std::string& access_control_origin);
static bool SniffForHTML(base::StringPiece data);
static bool SniffForXML(base::StringPiece data);
static bool SniffForJSON(base::StringPiece data);
// TODO(dsjang): this is only needed for collecting UMA stat. Will be deleted
// when this class is used for actual blocking.
static bool SniffForJS(base::StringPiece data);
// Never needs to be constructed/destructed.
SiteIsolationPolicy() {}
~SiteIsolationPolicy() {}
DISALLOW_COPY_AND_ASSIGN(SiteIsolationPolicy);
};
} // namespace content
#endif // CONTENT_CHILD_SITE_ISOLATION_POLICY_H_
|