From 282bfb6c1129224b9ec477342371c0b6cb569d6e Mon Sep 17 00:00:00 2001 From: DayShift <2922897389@qq.com> Date: Wed, 22 Jan 2025 09:54:05 +0800 Subject: [PATCH 1/7] Fix the regular expression in the getDuration method to prevent ReDoS attacks and update error messages in test cases. --- server/modules/apicache/apicache.js | 2 +- test/backend-test/test-apicache-ReDos.js | 26 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/backend-test/test-apicache-ReDos.js diff --git a/server/modules/apicache/apicache.js b/server/modules/apicache/apicache.js index 41930b24d..58f5e1971 100644 --- a/server/modules/apicache/apicache.js +++ b/server/modules/apicache/apicache.js @@ -485,7 +485,7 @@ function ApiCache() { } if (typeof duration === "string") { - let split = duration.match(/^([\d\.,]+)\s?(\w+)$/); + let split = duration.match(/^([\d\.,]+)\s?((?:(?!\d)\w)+)$/); if (split.length === 3) { let len = parseFloat(split[1]); diff --git a/test/backend-test/test-apicache-ReDos.js b/test/backend-test/test-apicache-ReDos.js new file mode 100644 index 000000000..cfaa79e9a --- /dev/null +++ b/test/backend-test/test-apicache-ReDos.js @@ -0,0 +1,26 @@ +const semver = require("semver"); +let test; +const nodeVersion = process.versions.node; +if (semver.satisfies(nodeVersion, ">= 18")) { + test = require("node:test"); +} else { + test = require("test"); +} +const apicacheModule = require("../../server/modules/apicache/apicache.js"); + +const assert = require("node:assert"); + +test("Test ReDos - attack string", async (t) => { + const getDuration = apicacheModule.getDuration; + const str = "" + "00".repeat(100000) + "\u0000"; + const startTime = performance.now(); + try { + getDuration(str); + } catch (error) { + // pass + } + const endTime = performance.now(); + const elapsedTime = endTime - startTime; + const reDosThreshold = 9000; + assert(elapsedTime <= reDosThreshold, `🚨 Potential ReDoS Attack! getDuration method took ${elapsedTime.toFixed(2)} ms, exceeding threshold of ${reDosThreshold} ms.`); +}); From 6248ff1c5d9bd29d5c72a01b2ce5a77c741f554b Mon Sep 17 00:00:00 2001 From: DayShift <113507098+ShiyuBanzhou@users.noreply.github.com> Date: Wed, 22 Jan 2025 22:55:09 +0800 Subject: [PATCH 2/7] Update server/modules/apicache/apicache.js modified the regular term matching rule Co-authored-by: Frank Elsinga --- server/modules/apicache/apicache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/apicache/apicache.js b/server/modules/apicache/apicache.js index 58f5e1971..95a04d9e3 100644 --- a/server/modules/apicache/apicache.js +++ b/server/modules/apicache/apicache.js @@ -485,7 +485,7 @@ function ApiCache() { } if (typeof duration === "string") { - let split = duration.match(/^([\d\.,]+)\s?((?:(?!\d)\w)+)$/); + let split = duration.match(/^([\d\.,]+)\s?([a-zA-Z]+)$/); if (split.length === 3) { let len = parseFloat(split[1]); From d11975ea8c12e06c4512669e1201fdc7e2aa9e6c Mon Sep 17 00:00:00 2001 From: DayShift <113507098+ShiyuBanzhou@users.noreply.github.com> Date: Wed, 22 Jan 2025 22:55:50 +0800 Subject: [PATCH 3/7] Delete test/backend-test/test-apicache-ReDos.js remove the test file --- test/backend-test/test-apicache-ReDos.js | 26 ------------------------ 1 file changed, 26 deletions(-) delete mode 100644 test/backend-test/test-apicache-ReDos.js diff --git a/test/backend-test/test-apicache-ReDos.js b/test/backend-test/test-apicache-ReDos.js deleted file mode 100644 index cfaa79e9a..000000000 --- a/test/backend-test/test-apicache-ReDos.js +++ /dev/null @@ -1,26 +0,0 @@ -const semver = require("semver"); -let test; -const nodeVersion = process.versions.node; -if (semver.satisfies(nodeVersion, ">= 18")) { - test = require("node:test"); -} else { - test = require("test"); -} -const apicacheModule = require("../../server/modules/apicache/apicache.js"); - -const assert = require("node:assert"); - -test("Test ReDos - attack string", async (t) => { - const getDuration = apicacheModule.getDuration; - const str = "" + "00".repeat(100000) + "\u0000"; - const startTime = performance.now(); - try { - getDuration(str); - } catch (error) { - // pass - } - const endTime = performance.now(); - const elapsedTime = endTime - startTime; - const reDosThreshold = 9000; - assert(elapsedTime <= reDosThreshold, `🚨 Potential ReDoS Attack! getDuration method took ${elapsedTime.toFixed(2)} ms, exceeding threshold of ${reDosThreshold} ms.`); -}); From 2098d34c5be9e6f04d40e7a1e5b6f1d3041df03c Mon Sep 17 00:00:00 2001 From: DayShift <2922897389@qq.com> Date: Sat, 25 Jan 2025 19:46:17 +0800 Subject: [PATCH 4/7] fix the bug of regular item --- server/notification-providers/pushdeer.js | 2 +- server/notification-providers/whapi.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/notification-providers/pushdeer.js b/server/notification-providers/pushdeer.js index 276c2f476..428f44703 100644 --- a/server/notification-providers/pushdeer.js +++ b/server/notification-providers/pushdeer.js @@ -11,7 +11,7 @@ class PushDeer extends NotificationProvider { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { const okMsg = "Sent Successfully."; const serverUrl = notification.pushdeerServer || "https://api2.pushdeer.com"; - const url = `${serverUrl.trim().replace(/\/*$/, "")}/message/push`; + const url = `${serverUrl.trim().replace(/(? Date: Sun, 26 Jan 2025 01:15:39 +0800 Subject: [PATCH 5/7] Update server/notification-providers/pushdeer.js More concise and reasonable regular expression fix Co-authored-by: Frank Elsinga --- server/notification-providers/pushdeer.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/notification-providers/pushdeer.js b/server/notification-providers/pushdeer.js index 428f44703..e39d61d61 100644 --- a/server/notification-providers/pushdeer.js +++ b/server/notification-providers/pushdeer.js @@ -11,7 +11,8 @@ class PushDeer extends NotificationProvider { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { const okMsg = "Sent Successfully."; const serverUrl = notification.pushdeerServer || "https://api2.pushdeer.com"; - const url = `${serverUrl.trim().replace(/(? Date: Sun, 26 Jan 2025 01:28:58 +0800 Subject: [PATCH 6/7] Update whapi.js More concise and reasonable regular expression fix --- server/notification-providers/whapi.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/notification-providers/whapi.js b/server/notification-providers/whapi.js index 1ac8bdc8a..956c265e4 100644 --- a/server/notification-providers/whapi.js +++ b/server/notification-providers/whapi.js @@ -24,7 +24,7 @@ class Whapi extends NotificationProvider { "body": msg, }; - let url = (notification.whapiApiUrl || "https://gate.whapi.cloud/").replace(/(? Date: Sun, 26 Jan 2025 09:06:18 +0800 Subject: [PATCH 7/7] Fix unnecessary escape character in regular expression --- server/notification-providers/pushdeer.js | 2 +- server/notification-providers/whapi.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/notification-providers/pushdeer.js b/server/notification-providers/pushdeer.js index e39d61d61..b1f675957 100644 --- a/server/notification-providers/pushdeer.js +++ b/server/notification-providers/pushdeer.js @@ -12,7 +12,7 @@ class PushDeer extends NotificationProvider { const okMsg = "Sent Successfully."; const serverUrl = notification.pushdeerServer || "https://api2.pushdeer.com"; // capture group below is nessesary to prevent an ReDOS-attack - const url = `${serverUrl.trim().replace(/([^\/])\/+$/, "$1")}/message/push`; + const url = `${serverUrl.trim().replace(/([^/])\/+$/, "$1")}/message/push`; let valid = msg != null && monitorJSON != null && heartbeatJSON != null; diff --git a/server/notification-providers/whapi.js b/server/notification-providers/whapi.js index 956c265e4..d83dc470f 100644 --- a/server/notification-providers/whapi.js +++ b/server/notification-providers/whapi.js @@ -24,7 +24,7 @@ class Whapi extends NotificationProvider { "body": msg, }; - let url = (notification.whapiApiUrl || "https://gate.whapi.cloud/").replace(/([^\/])\/+$/, "$1") + "/messages/text"; + let url = (notification.whapiApiUrl || "https://gate.whapi.cloud/").replace(/([^/])\/+$/, "$1") + "/messages/text"; await axios.post(url, data, config);