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

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

Issue 2125343002: Ban cross origin WebSocket connections to the service protocol (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: skybrian review Created 4 years, 5 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 | « runtime/bin/main.cc ('k') | runtime/bin/vmservice/vmservice_io.dart » ('j') | 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 } 98 }
99 } 99 }
100 100
101 class Server { 101 class Server {
102 static const WEBSOCKET_PATH = '/ws'; 102 static const WEBSOCKET_PATH = '/ws';
103 static const ROOT_REDIRECT_PATH = '/index.html'; 103 static const ROOT_REDIRECT_PATH = '/index.html';
104 104
105 final VMService _service; 105 final VMService _service;
106 final String _ip; 106 final String _ip;
107 final int _port; 107 final int _port;
108 108 final bool _originCheckDisabled;
109 final List<String> _allowedOrigins = <String>[];
109 HttpServer _server; 110 HttpServer _server;
110 bool get running => _server != null; 111 bool get running => _server != null;
111 bool _displayMessages = false; 112 bool _displayMessages = false;
112 113
113 Server(this._service, this._ip, this._port) { 114 Server(this._service, this._ip, this._port, this._originCheckDisabled) {
114 _displayMessages = (_ip != '127.0.0.1' || _port != 8181); 115 _displayMessages = (_ip != '127.0.0.1' || _port != 8181);
115 } 116 }
116 117
118 void _addOrigin(String host, String port) {
119 String origin = 'http://$host:$port';
120 _allowedOrigins.add(origin);
121 }
122
123 bool _isAllowedOrigin(String origin) {
124 for (String allowedOrigin in _allowedOrigins) {
125 if (origin.startsWith(allowedOrigin)) {
126 return true;
127 }
128 }
129 return false;
130 }
131
132 bool _originCheck(HttpRequest request) {
133 if (_originCheckDisabled) {
134 // Always allow.
135 return true;
136 }
137 // First check the web-socket specific origin.
138 List<String> origins = request.headers["Sec-WebSocket-Origin"];
139 if (origins == null) {
140 // Fall back to the general Origin field.
141 origins = request.headers["Origin"];
142 }
143 if (origins == null) {
144 // No origin sent. This is a non-browser client or a same-origin request.
145 return true;
146 }
147 for (String origin in origins) {
148 if (_isAllowedOrigin(origin)) {
149 return true;
150 }
151 }
152 return false;
153 }
154
117 void _requestHandler(HttpRequest request) { 155 void _requestHandler(HttpRequest request) {
118 // Allow cross origin requests with 'observatory' header. 156 if (!_originCheck(request)) {
119 request.response.headers.add('Access-Control-Allow-Origin', '*'); 157 // This is a cross origin attempt to connect
120 request.response.headers.add('Access-Control-Allow-Headers', 158 request.response.close();
121 'Observatory-Version'); 159 return;
122 160 }
123 if (request.method != 'GET') { 161 if (request.method != 'GET') {
124 // Not a GET request. Do nothing. 162 // Not a GET request. Do nothing.
125 request.response.close(); 163 request.response.close();
126 return; 164 return;
127 } 165 }
128 166
129 final String path = 167 final String path =
130 request.uri.path == '/' ? ROOT_REDIRECT_PATH : request.uri.path; 168 request.uri.path == '/' ? ROOT_REDIRECT_PATH : request.uri.path;
131 169
132 if (path == WEBSOCKET_PATH) { 170 if (path == WEBSOCKET_PATH) {
(...skipping 25 matching lines...) Expand all
158 rethrow; 196 rethrow;
159 } 197 }
160 } 198 }
161 199
162 Future startup() { 200 Future startup() {
163 if (_server != null) { 201 if (_server != null) {
164 // Already running. 202 // Already running.
165 return new Future.value(this); 203 return new Future.value(this);
166 } 204 }
167 205
206 // Clear allowed origins.
207 _allowedOrigins.clear();
208
168 var address = new InternetAddress(_ip); 209 var address = new InternetAddress(_ip);
169 // Startup HTTP server. 210 // Startup HTTP server.
170 return HttpServer.bind(address, _port).then((s) { 211 return HttpServer.bind(address, _port).then((s) {
171 _server = s; 212 _server = s;
172 _server.listen(_requestHandler, cancelOnError: true); 213 _server.listen(_requestHandler, cancelOnError: true);
173 var ip = _server.address.address.toString(); 214 var ip = _server.address.address.toString();
174 var port = _server.port.toString(); 215 var port = _server.port.toString();
216 // Add the numeric ip and host name to our allowed origins.
217 _addOrigin(ip, port);
218 _addOrigin(_server.address.host.toString(), port);
219 // Explicitly add localhost and 127.0.0.1.
220 _addOrigin('localhost', port);
221 _addOrigin('127.0.0.1', port);
175 if (_displayMessages) { 222 if (_displayMessages) {
176 print('Observatory listening on http://$ip:$port'); 223 print('Observatory listening on http://$ip:$port');
177 } 224 }
178 // Server is up and running. 225 // Server is up and running.
179 _notifyServerState(ip, _server.port); 226 _notifyServerState(ip, _server.port);
180 onServerAddressChange('http://$ip:$port'); 227 onServerAddressChange('http://$ip:$port');
181 return this; 228 return this;
182 }).catchError((e, st) { 229 }).catchError((e, st) {
183 print('Could not start Observatory HTTP server:\n$e\n$st\n'); 230 print('Could not start Observatory HTTP server:\n$e\n$st\n');
184 _notifyServerState("", 0); 231 _notifyServerState("", 0);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 _notifyServerState("", 0); 267 _notifyServerState("", 0);
221 onServerAddressChange(null); 268 onServerAddressChange(null);
222 return this; 269 return this;
223 }); 270 });
224 } 271 }
225 272
226 } 273 }
227 274
228 void _notifyServerState(String ip, int port) 275 void _notifyServerState(String ip, int port)
229 native "VMServiceIO_NotifyServerState"; 276 native "VMServiceIO_NotifyServerState";
OLDNEW
« no previous file with comments | « runtime/bin/main.cc ('k') | runtime/bin/vmservice/vmservice_io.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698