From 3ef009de73c837f9025df8bba62572885c70c72f Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Wed, 22 May 2024 13:21:26 -0500 Subject: [PATCH] enfore min and max username lengths to prevent DOS via spam-length names --- server/endpoints/system.js | 2 +- server/models/user.js | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/server/endpoints/system.js b/server/endpoints/system.js index f4057a40..6c941b1c 100644 --- a/server/endpoints/system.js +++ b/server/endpoints/system.js @@ -1024,7 +1024,7 @@ function systemEndpoints(app) { const updates = {}; if (username) { - updates.username = String(username); + updates.username = User.validations.username(String(username)); } if (password) { updates.password = String(password); diff --git a/server/models/user.js b/server/models/user.js index a1aeb2c6..f08548af 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -10,6 +10,20 @@ const User = { "role", "suspended", ], + validations: { + username: (newValue = "") => { + try { + if (String(newValue).length > 100) + throw new Error("Username cannot be longer than 100 characters"); + if (String(newValue).length < 2) + throw new Error("Username must be at least 2 characters"); + return String(newValue); + } catch (e) { + throw new Error(e.message); + } + }, + }, + // validations for the above writable fields. castColumnValue: function (key, value) { switch (key) { @@ -36,9 +50,9 @@ const User = { const hashedPassword = bcrypt.hashSync(password, 10); const user = await prisma.users.create({ data: { - username, + username: this.validations.username(username), password: hashedPassword, - role, + role: String(role), }, }); return { user: this.filterFields(user), error: null }; @@ -75,7 +89,13 @@ const User = { // and force-casts to the proper type; Object.entries(updates).forEach(([key, value]) => { if (this.writable.includes(key)) { - updates[key] = this.castColumnValue(key, value); + if (this.validations.hasOwnProperty(key)) { + updates[key] = this.validations[key]( + this.castColumnValue(key, value) + ); + } else { + updates[key] = this.castColumnValue(key, value); + } return; } delete updates[key];