socket-function 0.76.0 → 0.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SocketFunction.ts +4 -0
- package/package.json +1 -1
- package/src/callHTTPHandler.ts +4 -15
- package/src/misc.ts +11 -0
- package/src/webSocketServer.ts +12 -8
package/SocketFunction.ts
CHANGED
|
@@ -65,6 +65,10 @@ export class SocketFunction {
|
|
|
65
65
|
|
|
66
66
|
public static HTTP_COMPRESS = false;
|
|
67
67
|
|
|
68
|
+
// If you have HTTP resources that require cookies you might to set `SocketFunction.COEP = "require-corp"`
|
|
69
|
+
// - Cross-origin-resource-policy.
|
|
70
|
+
public static COEP = "credentialless";
|
|
71
|
+
|
|
68
72
|
// In retrospect... dynamically changing the wire serializer is a BAD idea. If any calls happen
|
|
69
73
|
// before it is changed, things just break. Also, it needs to be changed on both sides,
|
|
70
74
|
// or else things break. Also, it is very hard to detect when the issue is different serializers
|
package/package.json
CHANGED
package/src/callHTTPHandler.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { isDataImmutable, performLocalCall } from "./callManager";
|
|
|
5
5
|
import { SocketFunction } from "../SocketFunction";
|
|
6
6
|
import { gzip } from "zlib";
|
|
7
7
|
import zlib from "zlib";
|
|
8
|
-
import { formatNumberSuffixed, sha256Hash } from "./misc";
|
|
8
|
+
import { formatNumberSuffixed, getRootDomain, sha256Hash } from "./misc";
|
|
9
9
|
import { getClientNodeId, getNodeId } from "./nodeCache";
|
|
10
10
|
|
|
11
11
|
let defaultHTTPCall: CallType | undefined;
|
|
@@ -65,8 +65,7 @@ export async function httpCallHandler(request: http.IncomingMessage, response: h
|
|
|
65
65
|
{
|
|
66
66
|
response.setHeader("Strict-Transport-Security", "max-age=63072000; includeSubDomains; preload");
|
|
67
67
|
response.setHeader("Cross-Origin-Opener-Policy", "same-origin-allow-popups");
|
|
68
|
-
|
|
69
|
-
response.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
|
|
68
|
+
response.setHeader("Cross-Origin-Embedder-Policy", SocketFunction.COEP);
|
|
70
69
|
|
|
71
70
|
let origin = request.headers.origin || request.headers.referer;
|
|
72
71
|
let allowed = false;
|
|
@@ -79,18 +78,8 @@ export async function httpCallHandler(request: http.IncomingMessage, response: h
|
|
|
79
78
|
if (!host) {
|
|
80
79
|
throw new Error("Missing host in request headers");
|
|
81
80
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
hostname = parts.slice(-2).join(".");
|
|
85
|
-
if (hostname.startsWith("https://")) {
|
|
86
|
-
hostname = hostname.slice("https://".length);
|
|
87
|
-
}
|
|
88
|
-
hostname = hostname.split(":")[0];
|
|
89
|
-
hostname = hostname.split("/")[0];
|
|
90
|
-
return hostname;
|
|
91
|
-
}
|
|
92
|
-
let hostDomain = rootDomain(host);
|
|
93
|
-
let originDomain = rootDomain(origin);
|
|
81
|
+
let hostDomain = getRootDomain(host);
|
|
82
|
+
let originDomain = getRootDomain(origin);
|
|
94
83
|
allowed = hostDomain === originDomain;
|
|
95
84
|
if (!allowed) {
|
|
96
85
|
console.log(`Rejected CORS, hostDomain: ${hostDomain} !== ${originDomain}`);
|
package/src/misc.ts
CHANGED
|
@@ -293,6 +293,17 @@ export function sort<T>(arr: T[], sortKey: (obj: T) => unknown) {
|
|
|
293
293
|
return arr;
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
+
export function getRootDomain(hostname: string) {
|
|
297
|
+
if (hostname.startsWith("https://")) {
|
|
298
|
+
hostname = hostname.slice("https://".length);
|
|
299
|
+
}
|
|
300
|
+
hostname = hostname.split("/")[0];
|
|
301
|
+
let parts = hostname.split(".");
|
|
302
|
+
hostname = parts.slice(-2).join(".");
|
|
303
|
+
hostname = hostname.split(":")[0];
|
|
304
|
+
return hostname;
|
|
305
|
+
}
|
|
306
|
+
|
|
296
307
|
export class QueueLimited<T> {
|
|
297
308
|
private items: T[] = [];
|
|
298
309
|
private nextIndex = 0;
|
package/src/webSocketServer.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { parseSNIExtension, parseTLSHello, SNIType } from "./tlsParsing";
|
|
|
11
11
|
import debugbreak from "debugbreak";
|
|
12
12
|
import { getNodeId } from "./nodeCache";
|
|
13
13
|
import crypto from "crypto";
|
|
14
|
-
import { Watchable, timeInHour, timeInMinute } from "./misc";
|
|
14
|
+
import { Watchable, getRootDomain, timeInHour, timeInMinute } from "./misc";
|
|
15
15
|
import { delay, runInfinitePoll, runInfinitePollCallAtStart } from "./batching";
|
|
16
16
|
import { magenta, red } from "./formatting/logColors";
|
|
17
17
|
import { yellow } from "./formatting/logColors";
|
|
@@ -133,12 +133,14 @@ export async function startSocketServer(
|
|
|
133
133
|
let originHeader = request.headers["origin"];
|
|
134
134
|
if (originHeader) {
|
|
135
135
|
try {
|
|
136
|
-
let host = new URL("ws://" + request.headers["host"]).hostname;
|
|
137
|
-
let origin = new URL(originHeader).hostname;
|
|
136
|
+
let host = getRootDomain(new URL("ws://" + request.headers["host"]).hostname);
|
|
137
|
+
let origin = getRootDomain(new URL(originHeader).hostname);
|
|
138
138
|
if (host !== origin && !allowedHostnames.has(origin)) {
|
|
139
139
|
throw new Error(`Invalid cross domain request, ${JSON.stringify(host)} !== ${JSON.stringify(origin)} (also not in config.allowedHostnames ${JSON.stringify(config.allowHostnames)})`);
|
|
140
140
|
}
|
|
141
141
|
} catch (e) {
|
|
142
|
+
// Destroy the socket, so we don't lock up the client
|
|
143
|
+
socket.destroy();
|
|
142
144
|
// NOTE: Just log, because invalid requests are guaranteed to happen, and
|
|
143
145
|
// there's no point wasting time looking at them.
|
|
144
146
|
console.log(e);
|
|
@@ -217,11 +219,13 @@ export async function startSocketServer(
|
|
|
217
219
|
console.log(buffer.toString("base64"));
|
|
218
220
|
}
|
|
219
221
|
let originalSNI = sni;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
if (sni) {
|
|
223
|
+
// Remove subdomains until we can find a domain
|
|
224
|
+
while (!sniServers.has(sni)) {
|
|
225
|
+
let parts = sni.split(".");
|
|
226
|
+
if (parts.length <= 2) break;
|
|
227
|
+
sni = parts.slice(1).join(".");
|
|
228
|
+
}
|
|
225
229
|
}
|
|
226
230
|
|
|
227
231
|
if (!sniServers.has(sni)) {
|