From 32b6129ae39babd002d48344c8cf98d5be1d9352 Mon Sep 17 00:00:00 2001 From: zefie Date: Sun, 3 May 2026 13:07:12 -0400 Subject: [PATCH] set domain name to minisrv.local, check content-length on proxies --- .../includes/classes/WTV-MSNTV2.js | 25 ++++++++++++++++++- .../includes/classes/WTVHTTP.js | 16 +++++++++++- zefie_wtvp_minisrv/includes/config.json | 2 +- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/zefie_wtvp_minisrv/includes/classes/WTV-MSNTV2.js b/zefie_wtvp_minisrv/includes/classes/WTV-MSNTV2.js index 61c183d1..8b2cd0e3 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTV-MSNTV2.js +++ b/zefie_wtvp_minisrv/includes/classes/WTV-MSNTV2.js @@ -135,7 +135,8 @@ class WTVMSNTV2 { handleData(socket, chunk) { socket.buffer = Buffer.concat([socket.buffer, chunk]); - if (socket.buffer.length > parseFloat(this.minisrv_config.services[service_name].max_response_size || 128) * 1024 * 1024) { + const maxRequestBytes = this.maxProxyResponseBytes; + if (socket.buffer.length > maxRequestBytes) { this.writeError(socket, 413, 'Request Entity Too Large'); socket.destroy(); return; @@ -169,6 +170,11 @@ class WTVMSNTV2 { }); const contentLength = parseInt(headers['content-length'] || '0', 10) || 0; + if (contentLength > 0 && contentLength > maxRequestBytes) { + this.writeError(socket, 413, 'Request Entity Too Large'); + socket.destroy(); + return; + } const requestLength = headerEnd + 4 + contentLength; if (socket.buffer.length < requestLength) return; @@ -376,6 +382,11 @@ class WTVMSNTV2 { } }); const contentLength = parseInt(headers['content-length'] || '0', 10) || 0; + const maxRequestBytes = this.maxProxyResponseBytes; + if (contentLength > 0 && contentLength > maxRequestBytes) { + this.writeError(socket, 413, 'Request Entity Too Large'); + return; + } const requestLength = headerEnd + 4 + contentLength; if (connection.buffer.length < requestLength) break; const body = connection.buffer.slice(headerEnd + 4, requestLength); @@ -1115,6 +1126,12 @@ class WTVMSNTV2 { } }); const contentLength = parseInt(headers['content-length'] || '0', 10) || 0; + const maxRequestBytes = this.maxProxyResponseBytes; + if (contentLength > 0 && contentLength > maxRequestBytes) { + this.writeError(socket, 413, 'Request Entity Too Large'); + socket.destroy(); + return; + } const requestLength = headerEnd + 4 + contentLength; if (socket.sslv2AppBuffer.length < requestLength) return; const body = socket.sslv2AppBuffer.slice(headerEnd + 4, requestLength); @@ -1242,6 +1259,12 @@ class WTVMSNTV2 { }); const contentLength = parseInt(headers['content-length'] || '0', 10) || 0; + const maxRequestBytes = this.maxProxyResponseBytes; + if (contentLength > 0 && contentLength > maxRequestBytes) { + this.writeError(tlsSocket, 413, 'Request Entity Too Large'); + tlsSocket.destroy(); + return; + } const requestLength = headerEnd + 4 + contentLength; if (tlsSocket.buffer.length < requestLength) return; diff --git a/zefie_wtvp_minisrv/includes/classes/WTVHTTP.js b/zefie_wtvp_minisrv/includes/classes/WTVHTTP.js index 7d9c5c7c..b18cad53 100644 --- a/zefie_wtvp_minisrv/includes/classes/WTVHTTP.js +++ b/zefie_wtvp_minisrv/includes/classes/WTVHTTP.js @@ -111,11 +111,24 @@ class WTVHTTP { } const req = this.proxy_agent.request(options, (res) => { let total_data = 0; + let abortedBySize = false; + const maxBytes = 1024 * 1024 * parseFloat(this.minisrv_config.services[request_type].max_response_size || 16); + const responseContentLength = parseInt(res.headers['content-length'] || res.headers['Content-Length'] || '0', 10) || 0; + if (responseContentLength > 0 && responseContentLength > maxBytes) { + console.warn(` * Proxy response contains Content-Length ${responseContentLength} bytes > limit ${maxBytes} bytes, destroying...`); + abortedBySize = true; + res.destroy(); + const errpage = this.wtvshared.doErrorPage(400, "The item chosen is too large to be used."); + this.sendToClient(socket, errpage[0], errpage[1]); + return; + } res.on('data', d => { + if (abortedBySize) return; data.push(d); total_data += d.length; - if (total_data > 1024 * 1024 * parseFloat(this.minisrv_config.services[request_type].max_response_size || 16)) { + if (total_data > maxBytes) { + abortedBySize = true; console.warn(` * Response data exceeded ${this.minisrv_config.services[request_type].max_response_size || 16}MB limit, destroying...`); res.destroy(); const errpage = this.wtvshared.doErrorPage(400, "The item chosen is too large to be used."); @@ -133,6 +146,7 @@ class WTVHTTP { }); res.on('end', () => { + if (abortedBySize) return; // For when http proxies behave correctly if (!this.minisrv_config.services[request_type].external_proxy_is_http1 || data.length > 0) { this.handleProxy(socket, request_type, request_headers, res, data); diff --git a/zefie_wtvp_minisrv/includes/config.json b/zefie_wtvp_minisrv/includes/config.json index 45f5c890..9a67290e 100644 --- a/zefie_wtvp_minisrv/includes/config.json +++ b/zefie_wtvp_minisrv/includes/config.json @@ -48,7 +48,7 @@ "show_diskmap": false, // Useful for debugging custom Diskmaps "unauthorized_url": "wtv-1800:/unauthorized?", // Where to send unauthorized users "enable_port_isolation": true, // Only respond to services on their correct ports - "domain_name": "wtv.zefie.com", // For usenet and future stuff, no need to change just yet, + "domain_name": "minisrv.local", // For MSNTV2 stuff "max_post_length": 20, // in megabytes "require_valid_ssid": false, // require a valid SSID (with valid CRC) "user_accounts": { // user account settings