Skip to content

Commit 9637208

Browse files
committed
Add a same-origin check for non-internal connected Websockets
1 parent 810834d commit 9637208

File tree

2 files changed

+41
-23
lines changed

2 files changed

+41
-23
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ v0.22 (trunk)
77
* Fix vcard-temp refresh
88
* Fix #1177 Refresh Ad-Hoc commande list when command finished
99
* Fix #1163 Ad-hoc command returns only one item (Prosŏdy)
10+
* Add a same-origin check for non-internal connected Websockets
1011

1112
v0.21.1
1213
---------------------------

Diff for: src/Movim/Daemon/Core.php

+40-23
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function __construct($loop, $baseuri)
5454

5555
// Generate Push Notification
5656
if (!file_exists(CACHE_PATH . 'vapid_keys.json')) {
57-
echo colorize("Generate and store the Push Notification VAPID keys", 'green')."\n";
57+
echo colorize("Generate and store the Push Notification VAPID keys", 'green') . "\n";
5858
$keyset = VAPID::createVapidKeys();
5959
file_put_contents(CACHE_PATH . 'vapid_keys.json', json_encode($keyset));
6060
}
@@ -63,17 +63,17 @@ public function __construct($loop, $baseuri)
6363
public function setWebsocket($port)
6464
{
6565
echo
66-
"\n".
67-
"--- ".colorize("Server Configuration - Apache", 'purple')." ---".
66+
"\n" .
67+
"--- " . colorize("Server Configuration - Apache", 'purple') . " ---" .
6868
"\n";
69-
echo colorize("Enable the Secure WebSocket to WebSocket tunneling", 'yellow')."\n# a2enmod proxy_wstunnel \n";
70-
echo colorize("Add this in your configuration file (default-ssl.conf)", 'yellow')."\nProxyPass /ws/ ws://127.0.0.1:{$port}/\n";
69+
echo colorize("Enable the Secure WebSocket to WebSocket tunneling", 'yellow') . "\n# a2enmod proxy_wstunnel \n";
70+
echo colorize("Add this in your configuration file (default-ssl.conf)", 'yellow') . "\nProxyPass /ws/ ws://127.0.0.1:{$port}/\n";
7171

7272
echo
73-
"\n".
74-
"--- ".colorize("Server Configuration - nginx", 'purple')." ---".
73+
"\n" .
74+
"--- " . colorize("Server Configuration - nginx", 'purple') . " ---" .
7575
"\n";
76-
echo colorize("Add this in your configuration file", 'yellow')."\n";
76+
echo colorize("Add this in your configuration file", 'yellow') . "\n";
7777
echo "location /ws/ {
7878
proxy_pass http://127.0.0.1:{$port}/;
7979
proxy_http_version 1.1;
@@ -88,10 +88,10 @@ public function setWebsocket($port)
8888
";
8989

9090
echo
91-
"\n".
92-
"--- ".colorize("Server Configuration - Caddy", 'purple')." ---".
91+
"\n" .
92+
"--- " . colorize("Server Configuration - Caddy", 'purple') . " ---" .
9393
"\n";
94-
echo colorize("Add this in your configuration file", 'yellow')."\nhandle /ws/* {
94+
echo colorize("Add this in your configuration file", 'yellow') . "\nhandle /ws/* {
9595
reverse_proxy localhost:8080
9696
}
9797
@@ -100,14 +100,19 @@ public function setWebsocket($port)
100100

101101
public function onOpen(ConnectionInterface $conn)
102102
{
103+
if (!$this->isTrustedConnection($conn)) $conn->close();
104+
103105
// WebSockets from the Browser
104106
$sid = $this->getSid($conn);
107+
105108
if ($sid != null) {
106109
$path = $this->getPath($conn);
107110

108111
if (in_array($path, $this->single)) {
109-
if (array_key_exists($sid, $this->singlelocks)
110-
&& array_key_exists($path, $this->singlelocks[$sid])) {
112+
if (
113+
array_key_exists($sid, $this->singlelocks)
114+
&& array_key_exists($path, $this->singlelocks[$sid])
115+
) {
111116
$this->singlelocks[$sid][$path]++;
112117
$conn->close(1008);
113118
} else {
@@ -167,8 +172,10 @@ public function onClose(ConnectionInterface $conn)
167172
$path = $this->getPath($conn);
168173

169174
if (in_array($path, $this->single)) {
170-
if (array_key_exists($sid, $this->singlelocks)
171-
&& array_key_exists($path, $this->singlelocks[$sid])) {
175+
if (
176+
array_key_exists($sid, $this->singlelocks)
177+
&& array_key_exists($path, $this->singlelocks[$sid])
178+
) {
172179
$this->singlelocks[$sid][$path]--;
173180
if ($this->singlelocks[$sid][$path] == 0) {
174181
unset($this->singlelocks[$sid][$path]);
@@ -197,8 +204,10 @@ private function registerCleaner()
197204
{
198205
$this->loop->addPeriodicTimer(5, function () {
199206
foreach ($this->sessions as $sid => $session) {
200-
if ($session->countClients() == 0
201-
&& $session->registered == null) {
207+
if (
208+
$session->countClients() == 0
209+
&& $session->registered == null
210+
) {
202211
$session->killLinker();
203212
}
204213

@@ -216,7 +225,7 @@ private function registerCleaner()
216225
private function cleanupDBSessions()
217226
{
218227
DBSession::where('active', false)
219-
->where('created_at', '<', date(MOVIM_SQL_DATE, time()-60))
228+
->where('created_at', '<', date(MOVIM_SQL_DATE, time() - 60))
220229
->delete();
221230
}
222231

@@ -225,7 +234,7 @@ private function cleanupDBSessions()
225234
*/
226235
private function cleanupPushSubscriptions()
227236
{
228-
PushSubscription::where('activity_at', '<', date(MOVIM_SQL_DATE, time()-(60*60*24*30)))
237+
PushSubscription::where('activity_at', '<', date(MOVIM_SQL_DATE, time() - (60 * 60 * 24 * 30)))
229238
->delete();
230239
}
231240

@@ -234,7 +243,7 @@ private function cleanupPushSubscriptions()
234243
*/
235244
private function cleanupEncryptedPasswords()
236245
{
237-
EncryptedPassword::where('updated_at', '<', date(MOVIM_SQL_DATE, time()-(60*60*24*7)))
246+
EncryptedPassword::where('updated_at', '<', date(MOVIM_SQL_DATE, time() - (60 * 60 * 24 * 7)))
238247
->delete();
239248
}
240249

@@ -267,7 +276,7 @@ private function getLanguage(ConnectionInterface $conn)
267276
private function getOffset(ConnectionInterface $conn)
268277
{
269278
parse_str($conn->httpRequest->getUri()->getQuery(), $arr);
270-
return (isset($arr['offset'])) ? invertSign(((int)$arr['offset'])*60) : 0;
279+
return (isset($arr['offset'])) ? invertSign(((int)$arr['offset']) * 60) : 0;
271280
}
272281

273282
private function getPath(ConnectionInterface $conn)
@@ -287,9 +296,17 @@ private function getSid(ConnectionInterface $conn)
287296

288297
private function getHeaderSid(ConnectionInterface $conn)
289298
{
290-
return ($conn->httpRequest->hasHeader('MOVIM_SESSION_ID')
291-
&& $conn->httpRequest->getHeader('MOVIM_DAEMON_KEY')[0] === $this->key)
299+
return ($conn->httpRequest->hasHeader('MOVIM_SESSION_ID'))
292300
? $conn->httpRequest->getHeader('MOVIM_SESSION_ID')[0]
293301
: null;
294302
}
303+
304+
private function isTrustedConnection(ConnectionInterface $conn): bool
305+
{
306+
$daemonKeyHeader = $conn->httpRequest->getHeader('MOVIM_DAEMON_KEY');
307+
$secFetchSiteHeader = $conn->httpRequest->getHeader('Sec-Fetch-Site');
308+
309+
return (is_array($daemonKeyHeader) && !empty($daemonKeyHeader) && $daemonKeyHeader[0] === $this->key)
310+
|| (is_array($secFetchSiteHeader) && !empty($secFetchSiteHeader) && $secFetchSiteHeader[0] == 'same-origin');
311+
}
295312
}

0 commit comments

Comments
 (0)