oidc-spa 8.4.8 → 8.5.2
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/README.md +2 -5
- package/core/createOidc.js +3 -1
- package/core/createOidc.js.map +1 -1
- package/core/earlyInit.d.ts +45 -7
- package/core/earlyInit.js +69 -153
- package/core/earlyInit.js.map +1 -1
- package/core/oidcClientTsUserToTokens.d.ts +1 -0
- package/core/oidcClientTsUserToTokens.js +11 -1
- package/core/oidcClientTsUserToTokens.js.map +1 -1
- package/core/tokenExfiltrationDefense.d.ts +6 -0
- package/core/tokenExfiltrationDefense.js +616 -0
- package/core/tokenExfiltrationDefense.js.map +1 -0
- package/core/tokenExfiltrationDefense_legacy.d.ts +8 -0
- package/core/tokenExfiltrationDefense_legacy.js +133 -0
- package/core/tokenExfiltrationDefense_legacy.js.map +1 -0
- package/core/tokenPlaceholderSubstitution.d.ts +13 -0
- package/core/tokenPlaceholderSubstitution.js +79 -0
- package/core/tokenPlaceholderSubstitution.js.map +1 -0
- package/esm/core/createOidc.js +3 -1
- package/esm/core/createOidc.js.map +1 -1
- package/esm/core/earlyInit.d.ts +45 -7
- package/esm/core/earlyInit.js +69 -153
- package/esm/core/earlyInit.js.map +1 -1
- package/esm/core/oidcClientTsUserToTokens.d.ts +1 -0
- package/esm/core/oidcClientTsUserToTokens.js +11 -1
- package/esm/core/oidcClientTsUserToTokens.js.map +1 -1
- package/esm/core/tokenExfiltrationDefense.d.ts +6 -0
- package/esm/core/tokenExfiltrationDefense.js +613 -0
- package/esm/core/tokenExfiltrationDefense.js.map +1 -0
- package/esm/core/tokenExfiltrationDefense_legacy.d.ts +8 -0
- package/esm/core/tokenExfiltrationDefense_legacy.js +130 -0
- package/esm/core/tokenExfiltrationDefense_legacy.js.map +1 -0
- package/esm/core/tokenPlaceholderSubstitution.d.ts +13 -0
- package/esm/core/tokenPlaceholderSubstitution.js +73 -0
- package/esm/core/tokenPlaceholderSubstitution.js.map +1 -0
- package/esm/tools/isDomain.d.ts +1 -0
- package/esm/tools/isDomain.js +16 -0
- package/esm/tools/isDomain.js.map +1 -0
- package/esm/tools/isHostnameAuthorized.d.ts +5 -0
- package/esm/tools/isHostnameAuthorized.js +74 -0
- package/esm/tools/isHostnameAuthorized.js.map +1 -0
- package/esm/tools/isLikelyDevServer.js +18 -10
- package/esm/tools/isLikelyDevServer.js.map +1 -1
- package/package.json +1 -1
- package/src/core/createOidc.ts +2 -0
- package/src/core/earlyInit.ts +138 -192
- package/src/core/oidcClientTsUserToTokens.ts +14 -0
- package/src/core/tokenExfiltrationDefense.ts +874 -0
- package/src/core/tokenExfiltrationDefense_legacy.ts +165 -0
- package/src/core/tokenPlaceholderSubstitution.ts +105 -0
- package/src/tools/isDomain.ts +18 -0
- package/src/tools/isHostnameAuthorized.ts +91 -0
- package/src/tools/isLikelyDevServer.ts +23 -11
- package/src/vite-plugin/handleClientEntrypoint.ts +57 -20
- package/src/vite-plugin/vite-plugin.ts +5 -10
- package/tools/isDomain.d.ts +1 -0
- package/tools/isDomain.js +19 -0
- package/tools/isDomain.js.map +1 -0
- package/tools/isHostnameAuthorized.d.ts +5 -0
- package/tools/isHostnameAuthorized.js +77 -0
- package/tools/isHostnameAuthorized.js.map +1 -0
- package/tools/isLikelyDevServer.js +18 -10
- package/tools/isLikelyDevServer.js.map +1 -1
- package/vite-plugin/handleClientEntrypoint.js +36 -17
- package/vite-plugin/handleClientEntrypoint.js.map +1 -1
- package/vite-plugin/vite-plugin.d.ts +3 -4
- package/vite-plugin/vite-plugin.js +1 -5
- package/vite-plugin/vite-plugin.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oidcClientTsUserToTokens.js","sourceRoot":"","sources":["../src/core/oidcClientTsUserToTokens.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"oidcClientTsUserToTokens.js","sourceRoot":"","sources":["../src/core/oidcClientTsUserToTokens.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.enableTokenExfiltrationDefense = enableTokenExfiltrationDefense;
|
|
4
|
+
const assert_1 = require("../tools/tsafe/assert");
|
|
5
|
+
const tokenPlaceholderSubstitution_1 = require("./tokenPlaceholderSubstitution");
|
|
6
|
+
const isHostnameAuthorized_1 = require("../tools/isHostnameAuthorized");
|
|
7
|
+
const viteHashedJsAssetPathRegExp = /\/assets\/[^/]+-[a-zA-Z0-9_-]{8}\.js$/;
|
|
8
|
+
function enableTokenExfiltrationDefense(params) {
|
|
9
|
+
const { resourceServersAllowedHostnames = [], serviceWorkersAllowedHostnames = [] } = params;
|
|
10
|
+
(0, tokenPlaceholderSubstitution_1.markTokenSubstitutionAdEnabled)();
|
|
11
|
+
patchFetchApiToSubstituteTokenPlaceholder({ resourceServersAllowedHostnames });
|
|
12
|
+
patchXMLHttpRequestApiToSubstituteTokenPlaceholder({ resourceServersAllowedHostnames });
|
|
13
|
+
patchWebSocketApiToSubstituteTokenPlaceholder({ resourceServersAllowedHostnames });
|
|
14
|
+
patchEventSourceApiToSubstituteTokenPlaceholder({ resourceServersAllowedHostnames });
|
|
15
|
+
patchNavigatorSendBeaconApiToSubstituteTokenPlaceholder({ resourceServersAllowedHostnames });
|
|
16
|
+
restrictServiceWorkerRegistration({ serviceWorkersAllowedHostnames });
|
|
17
|
+
runMonkeyPatchingPrevention();
|
|
18
|
+
}
|
|
19
|
+
function patchFetchApiToSubstituteTokenPlaceholder(params) {
|
|
20
|
+
const { resourceServersAllowedHostnames } = params;
|
|
21
|
+
const fetch_actual = window.fetch;
|
|
22
|
+
window.fetch = async function fetch(input, init) {
|
|
23
|
+
const request = input instanceof Request ? input : new Request(input, init);
|
|
24
|
+
prevent_fetching_of_hashed_js_assets: {
|
|
25
|
+
const { pathname } = new URL(request.url, window.location.href);
|
|
26
|
+
if (!viteHashedJsAssetPathRegExp.test(pathname)) {
|
|
27
|
+
break prevent_fetching_of_hashed_js_assets;
|
|
28
|
+
}
|
|
29
|
+
throw new Error("oidc-spa: Blocked request to hashed js static asset.");
|
|
30
|
+
}
|
|
31
|
+
let didSubstitute = false;
|
|
32
|
+
const headers = new Headers();
|
|
33
|
+
request.headers.forEach((value, key) => {
|
|
34
|
+
const nextValue = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(value);
|
|
35
|
+
if (nextValue !== value) {
|
|
36
|
+
didSubstitute = true;
|
|
37
|
+
}
|
|
38
|
+
headers.set(key, nextValue);
|
|
39
|
+
});
|
|
40
|
+
let body;
|
|
41
|
+
handle_body: {
|
|
42
|
+
from_init: {
|
|
43
|
+
if (!init) {
|
|
44
|
+
break from_init;
|
|
45
|
+
}
|
|
46
|
+
if (!init.body) {
|
|
47
|
+
break from_init;
|
|
48
|
+
}
|
|
49
|
+
if (input instanceof Request && input.body !== null) {
|
|
50
|
+
break from_init;
|
|
51
|
+
}
|
|
52
|
+
if (typeof init.body === "string") {
|
|
53
|
+
body = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(init.body);
|
|
54
|
+
if (init.body !== body) {
|
|
55
|
+
didSubstitute = true;
|
|
56
|
+
}
|
|
57
|
+
break handle_body;
|
|
58
|
+
}
|
|
59
|
+
if (init.body instanceof URLSearchParams) {
|
|
60
|
+
let didUrlSearchParamsSubstitute = false;
|
|
61
|
+
const next = new URLSearchParams();
|
|
62
|
+
init.body.forEach((value, key) => {
|
|
63
|
+
const nextValue = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(value);
|
|
64
|
+
if (nextValue !== value) {
|
|
65
|
+
didUrlSearchParamsSubstitute = true;
|
|
66
|
+
}
|
|
67
|
+
next.append(key, nextValue);
|
|
68
|
+
});
|
|
69
|
+
if (didUrlSearchParamsSubstitute) {
|
|
70
|
+
didSubstitute = true;
|
|
71
|
+
}
|
|
72
|
+
body = didUrlSearchParamsSubstitute ? next : init.body;
|
|
73
|
+
break handle_body;
|
|
74
|
+
}
|
|
75
|
+
if (init.body instanceof FormData) {
|
|
76
|
+
let didFormDataSubstitute = false;
|
|
77
|
+
const next = new FormData();
|
|
78
|
+
init.body.forEach((value, key) => {
|
|
79
|
+
if (typeof value === "string") {
|
|
80
|
+
const nextValue = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(value);
|
|
81
|
+
if (nextValue !== value) {
|
|
82
|
+
didFormDataSubstitute = true;
|
|
83
|
+
}
|
|
84
|
+
next.append(key, nextValue);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
next.append(key, value);
|
|
88
|
+
});
|
|
89
|
+
if (didFormDataSubstitute) {
|
|
90
|
+
didSubstitute = true;
|
|
91
|
+
}
|
|
92
|
+
body = didFormDataSubstitute ? next : init.body;
|
|
93
|
+
break handle_body;
|
|
94
|
+
}
|
|
95
|
+
if (init.body instanceof Blob) {
|
|
96
|
+
break from_init;
|
|
97
|
+
}
|
|
98
|
+
body = init.body;
|
|
99
|
+
break handle_body;
|
|
100
|
+
}
|
|
101
|
+
if (request.body === null) {
|
|
102
|
+
body = undefined;
|
|
103
|
+
break handle_body;
|
|
104
|
+
}
|
|
105
|
+
const shouldInspectBody = (() => {
|
|
106
|
+
let ct = request.headers.get("Content-Type");
|
|
107
|
+
if (ct === null) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
ct = ct.toLocaleLowerCase();
|
|
111
|
+
if (!ct.startsWith("application/json") &&
|
|
112
|
+
!ct.startsWith("application/x-www-form-urlencoded")) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
const len_str = request.headers.get("Content-Length");
|
|
116
|
+
if (!len_str) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
const len = parseInt(len_str, 10);
|
|
120
|
+
if (!Number.isFinite(len) || len > 100000) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
})();
|
|
125
|
+
if (!shouldInspectBody) {
|
|
126
|
+
body = request.body;
|
|
127
|
+
break handle_body;
|
|
128
|
+
}
|
|
129
|
+
const bodyText = await request.clone().text();
|
|
130
|
+
const nextBodyText = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(bodyText);
|
|
131
|
+
if (nextBodyText !== bodyText) {
|
|
132
|
+
didSubstitute = true;
|
|
133
|
+
}
|
|
134
|
+
body = nextBodyText;
|
|
135
|
+
}
|
|
136
|
+
block_authed_request_to_unauthorized_hostnames: {
|
|
137
|
+
if (!didSubstitute) {
|
|
138
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
139
|
+
}
|
|
140
|
+
const { hostname } = new URL(request.url, window.location.href);
|
|
141
|
+
if ((0, isHostnameAuthorized_1.getIsHostnameAuthorized)({
|
|
142
|
+
allowedHostnames: resourceServersAllowedHostnames,
|
|
143
|
+
extendAuthorizationToParentDomain: true,
|
|
144
|
+
hostname
|
|
145
|
+
})) {
|
|
146
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
147
|
+
}
|
|
148
|
+
throw new Error([
|
|
149
|
+
`oidc-spa: Blocked authed request to ${hostname}.`,
|
|
150
|
+
`To authorize this request add "${hostname}" to`,
|
|
151
|
+
"`resourceServersAllowedHostnames`."
|
|
152
|
+
].join(" "));
|
|
153
|
+
}
|
|
154
|
+
const nextInit = {
|
|
155
|
+
method: request.method,
|
|
156
|
+
headers,
|
|
157
|
+
body,
|
|
158
|
+
mode: request.mode,
|
|
159
|
+
credentials: request.credentials,
|
|
160
|
+
cache: request.cache,
|
|
161
|
+
redirect: request.redirect,
|
|
162
|
+
referrer: request.referrer,
|
|
163
|
+
referrerPolicy: request.referrerPolicy,
|
|
164
|
+
integrity: request.integrity,
|
|
165
|
+
keepalive: request.keepalive,
|
|
166
|
+
signal: request.signal
|
|
167
|
+
};
|
|
168
|
+
{
|
|
169
|
+
//@ts-expect-error
|
|
170
|
+
const duplex = init?.duplex ?? (input instanceof Request ? input.duplex : undefined);
|
|
171
|
+
if (duplex !== undefined) {
|
|
172
|
+
//@ts-expect-error
|
|
173
|
+
nextInit.duplex = duplex;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return fetch_actual(request.url, nextInit);
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function patchXMLHttpRequestApiToSubstituteTokenPlaceholder(params) {
|
|
180
|
+
const { resourceServersAllowedHostnames } = params;
|
|
181
|
+
const open_actual = XMLHttpRequest.prototype.open;
|
|
182
|
+
const send_actual = XMLHttpRequest.prototype.send;
|
|
183
|
+
const setRequestHeader_actual = XMLHttpRequest.prototype.setRequestHeader;
|
|
184
|
+
const xhrDataSymbol = Symbol("oidc-spa XMLHttpRequest data");
|
|
185
|
+
const getXhrData = (xhr) => {
|
|
186
|
+
const xhr_any = xhr;
|
|
187
|
+
if (xhr_any[xhrDataSymbol] !== undefined) {
|
|
188
|
+
return xhr_any[xhrDataSymbol];
|
|
189
|
+
}
|
|
190
|
+
const data = {
|
|
191
|
+
url: "",
|
|
192
|
+
didSubstitute: false
|
|
193
|
+
};
|
|
194
|
+
xhr_any[xhrDataSymbol] = data;
|
|
195
|
+
return data;
|
|
196
|
+
};
|
|
197
|
+
XMLHttpRequest.prototype.open = function open(method, url, async, username, password) {
|
|
198
|
+
const xhrData = getXhrData(this);
|
|
199
|
+
xhrData.url = typeof url === "string" ? url : url.href;
|
|
200
|
+
xhrData.didSubstitute = false;
|
|
201
|
+
if (async === undefined) {
|
|
202
|
+
return open_actual.bind(this)(method, url);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
return open_actual.call(this, method, url, async, username, password);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
XMLHttpRequest.prototype.setRequestHeader = function setRequestHeader(name, value) {
|
|
209
|
+
const xhrData = getXhrData(this);
|
|
210
|
+
const nextValue = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(value);
|
|
211
|
+
if (nextValue !== value) {
|
|
212
|
+
xhrData.didSubstitute = true;
|
|
213
|
+
}
|
|
214
|
+
return setRequestHeader_actual.call(this, name, nextValue);
|
|
215
|
+
};
|
|
216
|
+
XMLHttpRequest.prototype.send = function send(body) {
|
|
217
|
+
const xhrData = getXhrData(this);
|
|
218
|
+
prevent_fetching_of_hashed_js_assets: {
|
|
219
|
+
const { pathname } = new URL(xhrData.url, window.location.href);
|
|
220
|
+
if (!viteHashedJsAssetPathRegExp.test(pathname)) {
|
|
221
|
+
break prevent_fetching_of_hashed_js_assets;
|
|
222
|
+
}
|
|
223
|
+
throw new Error("oidc-spa: Blocked request to hashed static asset.");
|
|
224
|
+
}
|
|
225
|
+
let nextBody = body;
|
|
226
|
+
if (typeof body === "string") {
|
|
227
|
+
const nextBodyText = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(body);
|
|
228
|
+
if (nextBodyText !== body) {
|
|
229
|
+
xhrData.didSubstitute = true;
|
|
230
|
+
}
|
|
231
|
+
nextBody = nextBodyText;
|
|
232
|
+
}
|
|
233
|
+
block_authed_request_to_unauthorized_hostnames: {
|
|
234
|
+
if (!xhrData.didSubstitute) {
|
|
235
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
236
|
+
}
|
|
237
|
+
const { hostname } = new URL(xhrData.url, window.location.href);
|
|
238
|
+
if ((0, isHostnameAuthorized_1.getIsHostnameAuthorized)({
|
|
239
|
+
allowedHostnames: resourceServersAllowedHostnames,
|
|
240
|
+
extendAuthorizationToParentDomain: true,
|
|
241
|
+
hostname
|
|
242
|
+
})) {
|
|
243
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
244
|
+
}
|
|
245
|
+
throw new Error([
|
|
246
|
+
`oidc-spa: Blocked authed request to ${hostname}.`,
|
|
247
|
+
`To authorize this request add "${hostname}" to`,
|
|
248
|
+
"`resourceServersAllowedHostnames`."
|
|
249
|
+
].join(" "));
|
|
250
|
+
}
|
|
251
|
+
return send_actual.call(this, nextBody);
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function patchWebSocketApiToSubstituteTokenPlaceholder(params) {
|
|
255
|
+
const { resourceServersAllowedHostnames } = params;
|
|
256
|
+
const WebSocket_actual = window.WebSocket;
|
|
257
|
+
const send_actual = WebSocket_actual.prototype.send;
|
|
258
|
+
const wsDataByWs = new WeakMap();
|
|
259
|
+
const WebSocketPatched = function WebSocket(url, protocols) {
|
|
260
|
+
const urlStr = typeof url === "string" ? url : url.href;
|
|
261
|
+
const nextUrl = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(urlStr);
|
|
262
|
+
let didSubstitute = nextUrl !== urlStr;
|
|
263
|
+
const nextProtocols = (() => {
|
|
264
|
+
if (protocols === undefined) {
|
|
265
|
+
return protocols;
|
|
266
|
+
}
|
|
267
|
+
if (typeof protocols === "string") {
|
|
268
|
+
const next = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(protocols);
|
|
269
|
+
if (next !== protocols) {
|
|
270
|
+
didSubstitute = true;
|
|
271
|
+
}
|
|
272
|
+
return next;
|
|
273
|
+
}
|
|
274
|
+
let didProtocolsSubstitute = false;
|
|
275
|
+
const next = protocols.map(protocol => {
|
|
276
|
+
const nextProtocol = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(protocol);
|
|
277
|
+
if (nextProtocol !== protocol) {
|
|
278
|
+
didProtocolsSubstitute = true;
|
|
279
|
+
}
|
|
280
|
+
return nextProtocol;
|
|
281
|
+
});
|
|
282
|
+
if (didProtocolsSubstitute) {
|
|
283
|
+
didSubstitute = true;
|
|
284
|
+
}
|
|
285
|
+
return next;
|
|
286
|
+
})();
|
|
287
|
+
const { hostname, pathname } = new URL(nextUrl, window.location.href);
|
|
288
|
+
block_authed_request_to_unauthorized_hostnames: {
|
|
289
|
+
if (!didSubstitute) {
|
|
290
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
291
|
+
}
|
|
292
|
+
if ((0, isHostnameAuthorized_1.getIsHostnameAuthorized)({
|
|
293
|
+
allowedHostnames: resourceServersAllowedHostnames,
|
|
294
|
+
extendAuthorizationToParentDomain: true,
|
|
295
|
+
hostname
|
|
296
|
+
})) {
|
|
297
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
298
|
+
}
|
|
299
|
+
throw new Error([
|
|
300
|
+
`oidc-spa: Blocked authed request to ${hostname}.`,
|
|
301
|
+
`To authorize this request add "${hostname}" to`,
|
|
302
|
+
"`resourceServersAllowedHostnames`."
|
|
303
|
+
].join(" "));
|
|
304
|
+
}
|
|
305
|
+
const ws = new WebSocket_actual(nextUrl, nextProtocols);
|
|
306
|
+
wsDataByWs.set(ws, {
|
|
307
|
+
url: nextUrl,
|
|
308
|
+
hostname,
|
|
309
|
+
pathname,
|
|
310
|
+
didSubstitute
|
|
311
|
+
});
|
|
312
|
+
return ws;
|
|
313
|
+
};
|
|
314
|
+
WebSocketPatched.prototype = WebSocket_actual.prototype;
|
|
315
|
+
for (const name of ["CONNECTING", "OPEN", "CLOSING", "CLOSED"]) {
|
|
316
|
+
Object.defineProperty(WebSocketPatched, name, {
|
|
317
|
+
value: WebSocket_actual[name],
|
|
318
|
+
writable: false,
|
|
319
|
+
enumerable: true,
|
|
320
|
+
configurable: false
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
window.WebSocket = WebSocketPatched;
|
|
324
|
+
WebSocket_actual.prototype.send = function send(data) {
|
|
325
|
+
const wsData = wsDataByWs.get(this);
|
|
326
|
+
if (wsData === undefined) {
|
|
327
|
+
// NOTE: This can happen for Vite's dev server websocket
|
|
328
|
+
return send_actual.call(this, data);
|
|
329
|
+
}
|
|
330
|
+
let nextData = data;
|
|
331
|
+
if (typeof data === "string") {
|
|
332
|
+
const nextDataText = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(data);
|
|
333
|
+
if (nextDataText !== data) {
|
|
334
|
+
wsData.didSubstitute = true;
|
|
335
|
+
}
|
|
336
|
+
nextData = nextDataText;
|
|
337
|
+
}
|
|
338
|
+
block_authed_request_to_unauthorized_hostnames: {
|
|
339
|
+
if (!wsData.didSubstitute) {
|
|
340
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
341
|
+
}
|
|
342
|
+
if ((0, isHostnameAuthorized_1.getIsHostnameAuthorized)({
|
|
343
|
+
allowedHostnames: resourceServersAllowedHostnames,
|
|
344
|
+
extendAuthorizationToParentDomain: true,
|
|
345
|
+
hostname: wsData.hostname
|
|
346
|
+
})) {
|
|
347
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
348
|
+
}
|
|
349
|
+
throw new Error([
|
|
350
|
+
`oidc-spa: Blocked authed request to ${wsData.hostname}.`,
|
|
351
|
+
`To authorize this request add "${wsData.hostname}" to`,
|
|
352
|
+
"`resourceServersAllowedHostnames`."
|
|
353
|
+
].join(" "));
|
|
354
|
+
}
|
|
355
|
+
prevent_fetching_of_hashed_js_assets: {
|
|
356
|
+
if (!viteHashedJsAssetPathRegExp.test(wsData.pathname)) {
|
|
357
|
+
break prevent_fetching_of_hashed_js_assets;
|
|
358
|
+
}
|
|
359
|
+
throw new Error("oidc-spa: Blocked request to hashed static asset.");
|
|
360
|
+
}
|
|
361
|
+
return send_actual.call(this, nextData);
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
function patchEventSourceApiToSubstituteTokenPlaceholder(params) {
|
|
365
|
+
const { resourceServersAllowedHostnames } = params;
|
|
366
|
+
const EventSource_actual = window.EventSource;
|
|
367
|
+
if (EventSource_actual === undefined) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const EventSourcePatched = function EventSource(url, eventSourceInitDict) {
|
|
371
|
+
const urlStr = typeof url === "string" ? url : url.href;
|
|
372
|
+
const nextUrl = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(urlStr);
|
|
373
|
+
const didSubstitute = nextUrl !== urlStr;
|
|
374
|
+
const { hostname } = new URL(nextUrl, window.location.href);
|
|
375
|
+
block_authed_request_to_unauthorized_hostnames: {
|
|
376
|
+
if (!didSubstitute) {
|
|
377
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
378
|
+
}
|
|
379
|
+
if ((0, isHostnameAuthorized_1.getIsHostnameAuthorized)({
|
|
380
|
+
allowedHostnames: resourceServersAllowedHostnames,
|
|
381
|
+
extendAuthorizationToParentDomain: true,
|
|
382
|
+
hostname
|
|
383
|
+
})) {
|
|
384
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
385
|
+
}
|
|
386
|
+
throw new Error([
|
|
387
|
+
`oidc-spa: Blocked authed request to ${hostname}.`,
|
|
388
|
+
`To authorize this request add "${hostname}" to`,
|
|
389
|
+
"`resourceServersAllowedHostnames`."
|
|
390
|
+
].join(" "));
|
|
391
|
+
}
|
|
392
|
+
return new EventSource_actual(nextUrl, eventSourceInitDict);
|
|
393
|
+
};
|
|
394
|
+
EventSourcePatched.prototype = EventSource_actual.prototype;
|
|
395
|
+
if ("CONNECTING" in EventSource_actual) {
|
|
396
|
+
for (const name of ["CONNECTING", "OPEN", "CLOSED"]) {
|
|
397
|
+
Object.defineProperty(EventSourcePatched, name, {
|
|
398
|
+
value: EventSource_actual[name],
|
|
399
|
+
writable: false,
|
|
400
|
+
enumerable: true,
|
|
401
|
+
configurable: false
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
window.EventSource = EventSourcePatched;
|
|
406
|
+
}
|
|
407
|
+
function patchNavigatorSendBeaconApiToSubstituteTokenPlaceholder(params) {
|
|
408
|
+
const { resourceServersAllowedHostnames } = params;
|
|
409
|
+
const sendBeacon_actual = navigator.sendBeacon?.bind(navigator);
|
|
410
|
+
if (sendBeacon_actual === undefined) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
navigator.sendBeacon = function sendBeacon(url, data) {
|
|
414
|
+
const urlStr = typeof url === "string" ? url : url.href;
|
|
415
|
+
const nextUrl = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(urlStr);
|
|
416
|
+
let didSubstitute = nextUrl !== urlStr;
|
|
417
|
+
const { hostname } = new URL(nextUrl, window.location.href);
|
|
418
|
+
let nextData = data;
|
|
419
|
+
if (typeof data === "string") {
|
|
420
|
+
const next = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(data);
|
|
421
|
+
if (next !== data) {
|
|
422
|
+
didSubstitute = true;
|
|
423
|
+
}
|
|
424
|
+
nextData = next;
|
|
425
|
+
}
|
|
426
|
+
else if (data instanceof URLSearchParams) {
|
|
427
|
+
let didUrlSearchParamsSubstitute = false;
|
|
428
|
+
const next = new URLSearchParams();
|
|
429
|
+
data.forEach((value, key) => {
|
|
430
|
+
const nextValue = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(value);
|
|
431
|
+
if (nextValue !== value) {
|
|
432
|
+
didUrlSearchParamsSubstitute = true;
|
|
433
|
+
}
|
|
434
|
+
next.append(key, nextValue);
|
|
435
|
+
});
|
|
436
|
+
if (didUrlSearchParamsSubstitute) {
|
|
437
|
+
didSubstitute = true;
|
|
438
|
+
nextData = next;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
else if (data instanceof FormData) {
|
|
442
|
+
let didFormDataSubstitute = false;
|
|
443
|
+
const next = new FormData();
|
|
444
|
+
data.forEach((value, key) => {
|
|
445
|
+
if (typeof value === "string") {
|
|
446
|
+
const nextValue = (0, tokenPlaceholderSubstitution_1.substitutePlaceholderByRealToken)(value);
|
|
447
|
+
if (nextValue !== value) {
|
|
448
|
+
didFormDataSubstitute = true;
|
|
449
|
+
}
|
|
450
|
+
next.append(key, nextValue);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
next.append(key, value);
|
|
454
|
+
});
|
|
455
|
+
if (didFormDataSubstitute) {
|
|
456
|
+
didSubstitute = true;
|
|
457
|
+
nextData = next;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
block_authed_request_to_unauthorized_hostnames: {
|
|
461
|
+
if (!didSubstitute) {
|
|
462
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
463
|
+
}
|
|
464
|
+
if ((0, isHostnameAuthorized_1.getIsHostnameAuthorized)({
|
|
465
|
+
allowedHostnames: resourceServersAllowedHostnames,
|
|
466
|
+
extendAuthorizationToParentDomain: true,
|
|
467
|
+
hostname
|
|
468
|
+
})) {
|
|
469
|
+
break block_authed_request_to_unauthorized_hostnames;
|
|
470
|
+
}
|
|
471
|
+
throw new Error([
|
|
472
|
+
`oidc-spa: Blocked authed request to ${hostname}.`,
|
|
473
|
+
`To authorize this request add "${hostname}" to`,
|
|
474
|
+
"`resourceServersAllowedHostnames`."
|
|
475
|
+
].join(" "));
|
|
476
|
+
}
|
|
477
|
+
return sendBeacon_actual(nextUrl, nextData);
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
function runMonkeyPatchingPrevention() {
|
|
481
|
+
const createWriteError = (target) => new Error([
|
|
482
|
+
`oidc-spa: Monkey patching of ${target} has been blocked.`,
|
|
483
|
+
`Read: https://docs.oidc-spa.dev/v/v8/resources/blocked-monkey-patching`
|
|
484
|
+
].join(" "));
|
|
485
|
+
for (const name of [
|
|
486
|
+
"fetch",
|
|
487
|
+
"XMLHttpRequest",
|
|
488
|
+
"WebSocket",
|
|
489
|
+
"Headers",
|
|
490
|
+
"URLSearchParams",
|
|
491
|
+
"EventSource",
|
|
492
|
+
"ServiceWorkerContainer",
|
|
493
|
+
"ServiceWorkerRegistration",
|
|
494
|
+
"ServiceWorker",
|
|
495
|
+
"FormData",
|
|
496
|
+
"Blob",
|
|
497
|
+
"String",
|
|
498
|
+
"Object",
|
|
499
|
+
"Promise",
|
|
500
|
+
"Array",
|
|
501
|
+
"RegExp",
|
|
502
|
+
"TextEncoder",
|
|
503
|
+
"Uint8Array",
|
|
504
|
+
"Uint32Array",
|
|
505
|
+
"Response",
|
|
506
|
+
"Reflect",
|
|
507
|
+
"JSON",
|
|
508
|
+
"encodeURIComponent",
|
|
509
|
+
"decodeURIComponent",
|
|
510
|
+
"atob",
|
|
511
|
+
"btoa"
|
|
512
|
+
]) {
|
|
513
|
+
const original = window[name];
|
|
514
|
+
if (!original) {
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
if ("prototype" in original) {
|
|
518
|
+
for (const propertyName of Object.getOwnPropertyNames(original.prototype)) {
|
|
519
|
+
if (name === "Object") {
|
|
520
|
+
if (propertyName === "toString" ||
|
|
521
|
+
propertyName === "constructor" ||
|
|
522
|
+
propertyName === "valueOf") {
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
if (name === "Array") {
|
|
527
|
+
if (propertyName === "constructor" || propertyName === "concat") {
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
const pd = Object.getOwnPropertyDescriptor(original.prototype, propertyName);
|
|
532
|
+
(0, assert_1.assert)(pd !== undefined);
|
|
533
|
+
if (!pd.configurable) {
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
Object.defineProperty(original.prototype, propertyName, {
|
|
537
|
+
enumerable: pd.enumerable,
|
|
538
|
+
configurable: false,
|
|
539
|
+
...("value" in pd
|
|
540
|
+
? {
|
|
541
|
+
get: () => pd.value,
|
|
542
|
+
set: () => {
|
|
543
|
+
throw createWriteError(`window.${name}.prototype.${propertyName}`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
: {
|
|
547
|
+
get: pd.get,
|
|
548
|
+
set: pd.set ??
|
|
549
|
+
(() => {
|
|
550
|
+
throw createWriteError(`window.${name}.prototype.${propertyName}`);
|
|
551
|
+
})
|
|
552
|
+
})
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
Object.defineProperty(window, name, {
|
|
557
|
+
configurable: false,
|
|
558
|
+
enumerable: true,
|
|
559
|
+
get: () => original,
|
|
560
|
+
set: () => {
|
|
561
|
+
throw createWriteError(`window.${name}`);
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
{
|
|
566
|
+
const name = "serviceWorker";
|
|
567
|
+
const original = navigator[name];
|
|
568
|
+
Object.defineProperty(navigator, name, {
|
|
569
|
+
configurable: false,
|
|
570
|
+
enumerable: true,
|
|
571
|
+
get: () => original,
|
|
572
|
+
set: () => {
|
|
573
|
+
throw createWriteError(`window.navigator.${name}`);
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
for (const name of ["call", "apply", "bind"]) {
|
|
578
|
+
const original = Function.prototype[name];
|
|
579
|
+
Object.defineProperty(Function.prototype, name, {
|
|
580
|
+
configurable: false,
|
|
581
|
+
enumerable: true,
|
|
582
|
+
get: () => original,
|
|
583
|
+
set: () => {
|
|
584
|
+
throw createWriteError(`window.Function.prototype.${name})`);
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
function restrictServiceWorkerRegistration(params) {
|
|
590
|
+
const { serviceWorkersAllowedHostnames } = params;
|
|
591
|
+
const { serviceWorker } = navigator;
|
|
592
|
+
const register_actual = serviceWorker.register.bind(serviceWorker);
|
|
593
|
+
serviceWorker.register = function register(scriptURL, options) {
|
|
594
|
+
const { hostname, protocol } = new URL(typeof scriptURL === "string" ? scriptURL : scriptURL.href, window.location.href);
|
|
595
|
+
if (protocol === "blob:") {
|
|
596
|
+
throw new Error([
|
|
597
|
+
"oidc-spa: Blocked service worker registration from blob.",
|
|
598
|
+
"Only solution: Set enableTokenExfiltrationDefense to false",
|
|
599
|
+
"or load the worker script from a remote url."
|
|
600
|
+
].join(" "));
|
|
601
|
+
}
|
|
602
|
+
if (!(0, isHostnameAuthorized_1.getIsHostnameAuthorized)({
|
|
603
|
+
allowedHostnames: serviceWorkersAllowedHostnames,
|
|
604
|
+
extendAuthorizationToParentDomain: false,
|
|
605
|
+
hostname
|
|
606
|
+
})) {
|
|
607
|
+
throw new Error([
|
|
608
|
+
`oidc-spa: Blocked service worker registration to ${hostname}.`,
|
|
609
|
+
`To authorize this registration add "${hostname}" to`,
|
|
610
|
+
"`serviceWorkersAllowedHostnames`."
|
|
611
|
+
].join(" "));
|
|
612
|
+
}
|
|
613
|
+
return register_actual(scriptURL, options);
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
//# sourceMappingURL=tokenExfiltrationDefense.js.map
|