bdy 1.25.20-stage → 1.25.21-dev
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/distTs/package.json
CHANGED
|
@@ -305,6 +305,17 @@ class AgentManagerClass {
|
|
|
305
305
|
res.statusCode = 404;
|
|
306
306
|
res.end('Not found');
|
|
307
307
|
}
|
|
308
|
+
// The server is bound to loopback, but a web page open on this machine can still
|
|
309
|
+
// reach it: a no-cors POST or an <img> fires without a preflight, a WebSocket is
|
|
310
|
+
// never subject to CORS, and DNS rebinding lets a page read the responses. bdy
|
|
311
|
+
// sends no Origin and always targets 127.0.0.1, browsers always send Origin on
|
|
312
|
+
// those requests and keep the rebound name in Host - so refuse either.
|
|
313
|
+
isLocalRequest(req) {
|
|
314
|
+
if (req.headers.origin !== undefined)
|
|
315
|
+
return false;
|
|
316
|
+
const host = req.headers.host;
|
|
317
|
+
return (host === `127.0.0.1:${this.port}` || host === `localhost:${this.port}`);
|
|
318
|
+
}
|
|
308
319
|
serverError(res, message) {
|
|
309
320
|
res.statusCode = 400;
|
|
310
321
|
res.end(JSON.stringify({
|
|
@@ -709,6 +720,11 @@ class AgentManagerClass {
|
|
|
709
720
|
}
|
|
710
721
|
async processRequest(req, res) {
|
|
711
722
|
logger_1.default.debug(`MANAGER REQUEST: ${req.url}`);
|
|
723
|
+
if (!this.isLocalRequest(req)) {
|
|
724
|
+
res.statusCode = 403;
|
|
725
|
+
res.end('Forbidden');
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
712
728
|
if (req.url === '/status')
|
|
713
729
|
return this.processStatus(res);
|
|
714
730
|
if (req.url === '/target')
|
|
@@ -751,6 +767,10 @@ class AgentManagerClass {
|
|
|
751
767
|
}
|
|
752
768
|
processUpgrade(req, socket, head) {
|
|
753
769
|
logger_1.default.debug(`MANAGER REQUEST: ${req.url}`);
|
|
770
|
+
if (!this.isLocalRequest(req)) {
|
|
771
|
+
socket.destroy();
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
754
774
|
const url = new URL(req.url || '', 'http://localhost');
|
|
755
775
|
const id = url.searchParams.get('id');
|
|
756
776
|
if (url.pathname === '/tunnel' && id && this.ws) {
|
|
@@ -801,7 +821,8 @@ class AgentManagerClass {
|
|
|
801
821
|
logger_1.default.error(err);
|
|
802
822
|
}
|
|
803
823
|
});
|
|
804
|
-
|
|
824
|
+
// Loopback only: the API has no credentials, every caller is a local bdy.
|
|
825
|
+
this.server.listen(this.port ?? 0, '127.0.0.1', () => {
|
|
805
826
|
logger_1.default.info(texts_1.LOG_AGENT_SERVER_STARTED);
|
|
806
827
|
});
|
|
807
828
|
}
|
|
@@ -10,7 +10,7 @@ const undici_1 = __importDefault(require("undici"));
|
|
|
10
10
|
const TIMEOUT = 120000;
|
|
11
11
|
const openSocket = (port, path) => {
|
|
12
12
|
return new Promise((resolve, reject) => {
|
|
13
|
-
const ws = new ws_1.WebSocket(`ws://
|
|
13
|
+
const ws = new ws_1.WebSocket(`ws://127.0.0.1:${port}${path}`);
|
|
14
14
|
ws.on('error', () => {
|
|
15
15
|
reject(new Error(texts_1.ERR_FAILED_TO_CONNECT_TO_AGENT));
|
|
16
16
|
});
|
|
@@ -26,7 +26,7 @@ const makeRequest = async (port, path, body) => {
|
|
|
26
26
|
}, TIMEOUT);
|
|
27
27
|
logger_1.default.debug(`TUNNEL API AGENT REQUEST: :${port}${path}`);
|
|
28
28
|
logger_1.default.debug(body);
|
|
29
|
-
const response = await undici_1.default.fetch(`http://
|
|
29
|
+
const response = await undici_1.default.fetch(`http://127.0.0.1:${port}${path}`, {
|
|
30
30
|
body: body ? JSON.stringify(body) : null,
|
|
31
31
|
headers: { 'Content-Type': 'application/json' },
|
|
32
32
|
method: 'POST',
|