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

Side by Side Diff: runtime/bin/vmservice/server.dart

Issue 2298943004: Fix bad origin check. (Closed)
Patch Set: . Created 4 years, 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of vmservice_io; 5 part of vmservice_io;
6 6
7 class WebSocketClient extends Client { 7 class WebSocketClient extends Client {
8 static const int PARSE_ERROR_CODE = 4000; 8 static const int PARSE_ERROR_CODE = 4000;
9 static const int BINARY_MESSAGE_ERROR_CODE = 4001; 9 static const int BINARY_MESSAGE_ERROR_CODE = 4001;
10 static const int NOT_MAP_ERROR_CODE = 4002; 10 static const int NOT_MAP_ERROR_CODE = 4002;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 map['socket'] = '$socket'; 72 map['socket'] = '$socket';
73 return map; 73 return map;
74 } 74 }
75 } 75 }
76 76
77 77
78 class HttpRequestClient extends Client { 78 class HttpRequestClient extends Client {
79 static ContentType jsonContentType = 79 static ContentType jsonContentType =
80 new ContentType("application", "json", charset: "utf-8"); 80 new ContentType("application", "json", charset: "utf-8");
81 final HttpRequest request; 81 final HttpRequest request;
82 final List<String> _allowedOrigins;
83 82
84 HttpRequestClient(this.request, VMService service, this._allowedOrigins) 83 HttpRequestClient(this.request, VMService service)
85 : super(service, sendEvents:false); 84 : super(service, sendEvents:false);
86 85
87 disconnect() { 86 disconnect() {
88 request.response.close(); 87 request.response.close();
89 close(); 88 close();
90 } 89 }
91 90
92 void post(dynamic result) { 91 void post(dynamic result) {
93 if (result == null) { 92 if (result == null) {
94 close(); 93 close();
95 return; 94 return;
96 } 95 }
97 HttpResponse response = request.response; 96 HttpResponse response = request.response;
97 // We closed the connection for bad origins earlier.
98 response.headers.add('Access-Control-Allow-Origin', '*');
98 response.headers.contentType = jsonContentType; 99 response.headers.contentType = jsonContentType;
99 final origins = request.headers['Origin'];
100 if ((origins != null) && (origins.isNotEmpty)) {
101 final uri = Uri.parse(origins.first);
102 final noPortOrigin = new Uri(host: uri.host, scheme: uri.scheme).origin;
103 if (_allowedOrigins.contains(noPortOrigin)) {
104 response.headers.add('Access-Control-Allow-Origin', uri.origin);
105 }
106 }
107 if (result is String) { 100 if (result is String) {
108 response.write(result); 101 response.write(result);
109 } else { 102 } else {
110 assert(result is List); 103 assert(result is List);
111 Uint8List cstring = result[0]; // Already in UTF-8. 104 Uint8List cstring = result[0]; // Already in UTF-8.
112 response.add(cstring); 105 response.add(cstring);
113 } 106 }
114 response.close(); 107 response.close();
115 close(); 108 close();
116 } 109 }
117 110
118 dynamic toJson() { 111 dynamic toJson() {
119 Map map = super.toJson(); 112 Map map = super.toJson();
120 map['type'] = 'HttpRequestClient'; 113 map['type'] = 'HttpRequestClient';
121 map['request'] = '$request'; 114 map['request'] = '$request';
122 return map; 115 return map;
123 } 116 }
124 } 117 }
125 118
126 class Server { 119 class Server {
127 static const WEBSOCKET_PATH = '/ws'; 120 static const WEBSOCKET_PATH = '/ws';
128 static const ROOT_REDIRECT_PATH = '/index.html'; 121 static const ROOT_REDIRECT_PATH = '/index.html';
129 122
130 final VMService _service; 123 final VMService _service;
131 final String _ip; 124 final String _ip;
132 final int _port; 125 final int _port;
133 final bool _originCheckDisabled; 126 final bool _originCheckDisabled;
134 final List<String> _allowedOrigins = <String>[];
135 HttpServer _server; 127 HttpServer _server;
136 bool get running => _server != null; 128 bool get running => _server != null;
137 bool _displayMessages = false; 129 bool _displayMessages = false;
138 130
139 Server(this._service, this._ip, this._port, this._originCheckDisabled) { 131 Server(this._service, this._ip, this._port, this._originCheckDisabled) {
140 _displayMessages = (_ip != '127.0.0.1' || _port != 8181); 132 _displayMessages = (_ip != '127.0.0.1' || _port != 8181);
141 } 133 }
142 134
143 void _addOrigin(String host, String port) { 135 bool _isAllowedOrigin(String origin) {
144 if (port == null) { 136 Uri uri;
145 String origin = 'http://$host'; 137 try {
146 _allowedOrigins.add(origin); 138 uri = Uri.parse(origin);
147 } else { 139 } catch (_) {
148 String origin = 'http://$host:$port'; 140 return false;
149 _allowedOrigins.add(origin);
150 } 141 }
151 }
152 142
153 bool _isAllowedOrigin(String origin) { 143 // Explicitly add localhost and 127.0.0.1 on any port (necessary for
154 for (String allowedOrigin in _allowedOrigins) { 144 // adb port forwarding).
155 if (origin.startsWith(allowedOrigin)) { 145 if ((uri.host == 'localhost') ||
156 return true; 146 (uri.host == '127.0.0.1')) {
157 } 147 return true;
158 } 148 }
149
150 if ((uri.port == _server.port) &&
151 ((uri.host == _server.address.address) ||
152 (uri.host == _server.address.host))) {
153 return true;
154 }
155
159 return false; 156 return false;
160 } 157 }
161 158
162 bool _originCheck(HttpRequest request) { 159 bool _originCheck(HttpRequest request) {
163 if (_originCheckDisabled) { 160 if (_originCheckDisabled) {
164 // Always allow. 161 // Always allow.
165 return true; 162 return true;
166 } 163 }
167 // First check the web-socket specific origin. 164 // First check the web-socket specific origin.
168 List<String> origins = request.headers["Sec-WebSocket-Origin"]; 165 List<String> origins = request.headers["Sec-WebSocket-Origin"];
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 if (asset != null) { 238 if (asset != null) {
242 // Serving up a static asset (e.g. .css, .html, .png). 239 // Serving up a static asset (e.g. .css, .html, .png).
243 request.response.headers.contentType = 240 request.response.headers.contentType =
244 ContentType.parse(asset.mimeType); 241 ContentType.parse(asset.mimeType);
245 request.response.add(asset.data); 242 request.response.add(asset.data);
246 request.response.close(); 243 request.response.close();
247 return; 244 return;
248 } 245 }
249 // HTTP based service request. 246 // HTTP based service request.
250 try { 247 try {
251 var client = new HttpRequestClient(request, _service, _allowedOrigins); 248 var client = new HttpRequestClient(request, _service);
252 var message = new Message.fromUri(client, request.uri); 249 var message = new Message.fromUri(client, request.uri);
253 client.onMessage(null, message); 250 client.onMessage(null, message);
254 } catch (e) { 251 } catch (e) {
255 print('Unexpected error processing HTTP request uri: ' 252 print('Unexpected error processing HTTP request uri: '
256 '${request.uri}\n$e\n'); 253 '${request.uri}\n$e\n');
257 rethrow; 254 rethrow;
258 } 255 }
259 } 256 }
260 257
261 Future startup() { 258 Future startup() {
262 if (_server != null) { 259 if (_server != null) {
263 // Already running. 260 // Already running.
264 return new Future.value(this); 261 return new Future.value(this);
265 } 262 }
266 263
267 // Clear allowed origins.
268 _allowedOrigins.clear();
269
270 var address = new InternetAddress(_ip); 264 var address = new InternetAddress(_ip);
271 // Startup HTTP server. 265 // Startup HTTP server.
272 return HttpServer.bind(address, _port).then((s) { 266 return HttpServer.bind(address, _port).then((s) {
273 _server = s; 267 _server = s;
274 _server.listen(_requestHandler, cancelOnError: true); 268 _server.listen(_requestHandler, cancelOnError: true);
275 var ip = _server.address.address.toString(); 269 var ip = _server.address.address;
276 var port = _server.port.toString(); 270 var port = _server.port;
277 // Add the numeric ip and host name to our allowed origins.
278 _addOrigin(ip, port);
279 _addOrigin(_server.address.host.toString(), port);
280 // Explicitly add localhost and 127.0.0.1 on any port (necessary for
281 // adb port forwarding).
282 _addOrigin('127.0.0.1', null);
283 _addOrigin('localhost', null);
284 if (_displayMessages) { 271 if (_displayMessages) {
285 print('Observatory listening on http://$ip:$port'); 272 print('Observatory listening on http://$ip:$port');
286 } 273 }
287 // Server is up and running. 274 // Server is up and running.
288 _notifyServerState(ip, _server.port); 275 _notifyServerState(ip, _server.port);
289 onServerAddressChange('http://$ip:$port'); 276 onServerAddressChange('http://$ip:$port');
290 return this; 277 return this;
291 }).catchError((e, st) { 278 }).catchError((e, st) {
292 print('Could not start Observatory HTTP server:\n$e\n$st\n'); 279 print('Could not start Observatory HTTP server:\n$e\n$st\n');
293 _notifyServerState("", 0); 280 _notifyServerState("", 0);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 _notifyServerState("", 0); 316 _notifyServerState("", 0);
330 onServerAddressChange(null); 317 onServerAddressChange(null);
331 return this; 318 return this;
332 }); 319 });
333 } 320 }
334 321
335 } 322 }
336 323
337 void _notifyServerState(String ip, int port) 324 void _notifyServerState(String ip, int port)
338 native "VMServiceIO_NotifyServerState"; 325 native "VMServiceIO_NotifyServerState";
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698