mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-22 06:00:56 +02:00
⚖️ feat: Add Violation Scores (#8304)
- Introduced new violation scores for TTS, STT, Fork, Import, and File Upload actions in the .env.example file. - Updated logViolation function to accept a score parameter, allowing for dynamic severity levels based on the action type. - Modified limiters for Fork, Import, Message, STT, TTS, Tool Call, and File Upload to utilize the new violation scores when logging violations.
This commit is contained in:
parent
916cd46221
commit
550610dba9
11 changed files with 61 additions and 14 deletions
|
@ -349,6 +349,11 @@ REGISTRATION_VIOLATION_SCORE=1
|
|||
CONCURRENT_VIOLATION_SCORE=1
|
||||
MESSAGE_VIOLATION_SCORE=1
|
||||
NON_BROWSER_VIOLATION_SCORE=20
|
||||
TTS_VIOLATION_SCORE=0
|
||||
STT_VIOLATION_SCORE=0
|
||||
FORK_VIOLATION_SCORE=0
|
||||
IMPORT_VIOLATION_SCORE=0
|
||||
FILE_UPLOAD_VIOLATION_SCORE=0
|
||||
|
||||
LOGIN_MAX=7
|
||||
LOGIN_WINDOW=5
|
||||
|
|
2
api/cache/logViolation.js
vendored
2
api/cache/logViolation.js
vendored
|
@ -9,7 +9,7 @@ const banViolation = require('./banViolation');
|
|||
* @param {Object} res - Express response object.
|
||||
* @param {string} type - The type of violation.
|
||||
* @param {Object} errorMessage - The error message to log.
|
||||
* @param {number} [score=1] - The severity of the violation. Defaults to 1
|
||||
* @param {number | string} [score=1] - The severity of the violation. Defaults to 1
|
||||
*/
|
||||
const logViolation = async (req, res, type, errorMessage, score = 1) => {
|
||||
const userId = req.user?.id ?? req.user?._id;
|
||||
|
|
|
@ -11,6 +11,7 @@ const getEnvironmentVariables = () => {
|
|||
const FORK_IP_WINDOW = parseInt(process.env.FORK_IP_WINDOW) || 1;
|
||||
const FORK_USER_MAX = parseInt(process.env.FORK_USER_MAX) || 7;
|
||||
const FORK_USER_WINDOW = parseInt(process.env.FORK_USER_WINDOW) || 1;
|
||||
const FORK_VIOLATION_SCORE = process.env.FORK_VIOLATION_SCORE;
|
||||
|
||||
const forkIpWindowMs = FORK_IP_WINDOW * 60 * 1000;
|
||||
const forkIpMax = FORK_IP_MAX;
|
||||
|
@ -27,12 +28,18 @@ const getEnvironmentVariables = () => {
|
|||
forkUserWindowMs,
|
||||
forkUserMax,
|
||||
forkUserWindowInMinutes,
|
||||
forkViolationScore: FORK_VIOLATION_SCORE,
|
||||
};
|
||||
};
|
||||
|
||||
const createForkHandler = (ip = true) => {
|
||||
const { forkIpMax, forkIpWindowInMinutes, forkUserMax, forkUserWindowInMinutes } =
|
||||
getEnvironmentVariables();
|
||||
const {
|
||||
forkIpMax,
|
||||
forkUserMax,
|
||||
forkViolationScore,
|
||||
forkIpWindowInMinutes,
|
||||
forkUserWindowInMinutes,
|
||||
} = getEnvironmentVariables();
|
||||
|
||||
return async (req, res) => {
|
||||
const type = ViolationTypes.FILE_UPLOAD_LIMIT;
|
||||
|
@ -43,7 +50,7 @@ const createForkHandler = (ip = true) => {
|
|||
windowInMinutes: ip ? forkIpWindowInMinutes : forkUserWindowInMinutes,
|
||||
};
|
||||
|
||||
await logViolation(req, res, type, errorMessage);
|
||||
await logViolation(req, res, type, errorMessage, forkViolationScore);
|
||||
res.status(429).json({ message: 'Too many conversation fork requests. Try again later' });
|
||||
};
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ const getEnvironmentVariables = () => {
|
|||
const IMPORT_IP_WINDOW = parseInt(process.env.IMPORT_IP_WINDOW) || 15;
|
||||
const IMPORT_USER_MAX = parseInt(process.env.IMPORT_USER_MAX) || 50;
|
||||
const IMPORT_USER_WINDOW = parseInt(process.env.IMPORT_USER_WINDOW) || 15;
|
||||
const IMPORT_VIOLATION_SCORE = process.env.IMPORT_VIOLATION_SCORE;
|
||||
|
||||
const importIpWindowMs = IMPORT_IP_WINDOW * 60 * 1000;
|
||||
const importIpMax = IMPORT_IP_MAX;
|
||||
|
@ -27,12 +28,18 @@ const getEnvironmentVariables = () => {
|
|||
importUserWindowMs,
|
||||
importUserMax,
|
||||
importUserWindowInMinutes,
|
||||
importViolationScore: IMPORT_VIOLATION_SCORE,
|
||||
};
|
||||
};
|
||||
|
||||
const createImportHandler = (ip = true) => {
|
||||
const { importIpMax, importIpWindowInMinutes, importUserMax, importUserWindowInMinutes } =
|
||||
getEnvironmentVariables();
|
||||
const {
|
||||
importIpMax,
|
||||
importUserMax,
|
||||
importViolationScore,
|
||||
importIpWindowInMinutes,
|
||||
importUserWindowInMinutes,
|
||||
} = getEnvironmentVariables();
|
||||
|
||||
return async (req, res) => {
|
||||
const type = ViolationTypes.FILE_UPLOAD_LIMIT;
|
||||
|
@ -43,7 +50,7 @@ const createImportHandler = (ip = true) => {
|
|||
windowInMinutes: ip ? importIpWindowInMinutes : importUserWindowInMinutes,
|
||||
};
|
||||
|
||||
await logViolation(req, res, type, errorMessage);
|
||||
await logViolation(req, res, type, errorMessage, importViolationScore);
|
||||
res.status(429).json({ message: 'Too many conversation import requests. Try again later' });
|
||||
};
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ const {
|
|||
MESSAGE_IP_WINDOW = 1,
|
||||
MESSAGE_USER_MAX = 40,
|
||||
MESSAGE_USER_WINDOW = 1,
|
||||
MESSAGE_VIOLATION_SCORE: score,
|
||||
} = process.env;
|
||||
|
||||
const ipWindowMs = MESSAGE_IP_WINDOW * 60 * 1000;
|
||||
|
@ -39,7 +40,7 @@ const createHandler = (ip = true) => {
|
|||
windowInMinutes: ip ? ipWindowInMinutes : userWindowInMinutes,
|
||||
};
|
||||
|
||||
await logViolation(req, res, type, errorMessage);
|
||||
await logViolation(req, res, type, errorMessage, score);
|
||||
return await denyRequest(req, res, errorMessage);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ const getEnvironmentVariables = () => {
|
|||
const STT_IP_WINDOW = parseInt(process.env.STT_IP_WINDOW) || 1;
|
||||
const STT_USER_MAX = parseInt(process.env.STT_USER_MAX) || 50;
|
||||
const STT_USER_WINDOW = parseInt(process.env.STT_USER_WINDOW) || 1;
|
||||
const STT_VIOLATION_SCORE = process.env.STT_VIOLATION_SCORE;
|
||||
|
||||
const sttIpWindowMs = STT_IP_WINDOW * 60 * 1000;
|
||||
const sttIpMax = STT_IP_MAX;
|
||||
|
@ -27,11 +28,12 @@ const getEnvironmentVariables = () => {
|
|||
sttUserWindowMs,
|
||||
sttUserMax,
|
||||
sttUserWindowInMinutes,
|
||||
sttViolationScore: STT_VIOLATION_SCORE,
|
||||
};
|
||||
};
|
||||
|
||||
const createSTTHandler = (ip = true) => {
|
||||
const { sttIpMax, sttIpWindowInMinutes, sttUserMax, sttUserWindowInMinutes } =
|
||||
const { sttIpMax, sttIpWindowInMinutes, sttUserMax, sttUserWindowInMinutes, sttViolationScore } =
|
||||
getEnvironmentVariables();
|
||||
|
||||
return async (req, res) => {
|
||||
|
@ -43,7 +45,7 @@ const createSTTHandler = (ip = true) => {
|
|||
windowInMinutes: ip ? sttIpWindowInMinutes : sttUserWindowInMinutes,
|
||||
};
|
||||
|
||||
await logViolation(req, res, type, errorMessage);
|
||||
await logViolation(req, res, type, errorMessage, sttViolationScore);
|
||||
res.status(429).json({ message: 'Too many STT requests. Try again later' });
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,6 +6,8 @@ const logViolation = require('~/cache/logViolation');
|
|||
const { isEnabled } = require('~/server/utils');
|
||||
const { logger } = require('~/config');
|
||||
|
||||
const { TOOL_CALL_VIOLATION_SCORE: score } = process.env;
|
||||
|
||||
const handler = async (req, res) => {
|
||||
const type = ViolationTypes.TOOL_CALL_LIMIT;
|
||||
const errorMessage = {
|
||||
|
@ -15,7 +17,7 @@ const handler = async (req, res) => {
|
|||
windowInMinutes: 1,
|
||||
};
|
||||
|
||||
await logViolation(req, res, type, errorMessage, 0);
|
||||
await logViolation(req, res, type, errorMessage, score);
|
||||
res.status(429).json({ message: 'Too many tool call requests. Try again later' });
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ const getEnvironmentVariables = () => {
|
|||
const TTS_IP_WINDOW = parseInt(process.env.TTS_IP_WINDOW) || 1;
|
||||
const TTS_USER_MAX = parseInt(process.env.TTS_USER_MAX) || 50;
|
||||
const TTS_USER_WINDOW = parseInt(process.env.TTS_USER_WINDOW) || 1;
|
||||
const TTS_VIOLATION_SCORE = process.env.TTS_VIOLATION_SCORE;
|
||||
|
||||
const ttsIpWindowMs = TTS_IP_WINDOW * 60 * 1000;
|
||||
const ttsIpMax = TTS_IP_MAX;
|
||||
|
@ -27,11 +28,12 @@ const getEnvironmentVariables = () => {
|
|||
ttsUserWindowMs,
|
||||
ttsUserMax,
|
||||
ttsUserWindowInMinutes,
|
||||
ttsViolationScore: TTS_VIOLATION_SCORE,
|
||||
};
|
||||
};
|
||||
|
||||
const createTTSHandler = (ip = true) => {
|
||||
const { ttsIpMax, ttsIpWindowInMinutes, ttsUserMax, ttsUserWindowInMinutes } =
|
||||
const { ttsIpMax, ttsIpWindowInMinutes, ttsUserMax, ttsUserWindowInMinutes, ttsViolationScore } =
|
||||
getEnvironmentVariables();
|
||||
|
||||
return async (req, res) => {
|
||||
|
@ -43,7 +45,7 @@ const createTTSHandler = (ip = true) => {
|
|||
windowInMinutes: ip ? ttsIpWindowInMinutes : ttsUserWindowInMinutes,
|
||||
};
|
||||
|
||||
await logViolation(req, res, type, errorMessage);
|
||||
await logViolation(req, res, type, errorMessage, ttsViolationScore);
|
||||
res.status(429).json({ message: 'Too many TTS requests. Try again later' });
|
||||
};
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ const getEnvironmentVariables = () => {
|
|||
const FILE_UPLOAD_IP_WINDOW = parseInt(process.env.FILE_UPLOAD_IP_WINDOW) || 15;
|
||||
const FILE_UPLOAD_USER_MAX = parseInt(process.env.FILE_UPLOAD_USER_MAX) || 50;
|
||||
const FILE_UPLOAD_USER_WINDOW = parseInt(process.env.FILE_UPLOAD_USER_WINDOW) || 15;
|
||||
const FILE_UPLOAD_VIOLATION_SCORE = process.env.FILE_UPLOAD_VIOLATION_SCORE;
|
||||
|
||||
const fileUploadIpWindowMs = FILE_UPLOAD_IP_WINDOW * 60 * 1000;
|
||||
const fileUploadIpMax = FILE_UPLOAD_IP_MAX;
|
||||
|
@ -27,6 +28,7 @@ const getEnvironmentVariables = () => {
|
|||
fileUploadUserWindowMs,
|
||||
fileUploadUserMax,
|
||||
fileUploadUserWindowInMinutes,
|
||||
fileUploadViolationScore: FILE_UPLOAD_VIOLATION_SCORE,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -36,6 +38,7 @@ const createFileUploadHandler = (ip = true) => {
|
|||
fileUploadIpWindowInMinutes,
|
||||
fileUploadUserMax,
|
||||
fileUploadUserWindowInMinutes,
|
||||
fileUploadViolationScore,
|
||||
} = getEnvironmentVariables();
|
||||
|
||||
return async (req, res) => {
|
||||
|
@ -47,7 +50,7 @@ const createFileUploadHandler = (ip = true) => {
|
|||
windowInMinutes: ip ? fileUploadIpWindowInMinutes : fileUploadUserWindowInMinutes,
|
||||
};
|
||||
|
||||
await logViolation(req, res, type, errorMessage);
|
||||
await logViolation(req, res, type, errorMessage, fileUploadViolationScore);
|
||||
res.status(429).json({ message: 'Too many file upload requests. Try again later' });
|
||||
};
|
||||
};
|
||||
|
|
|
@ -26,6 +26,15 @@ const config: PlaywrightTestConfig = {
|
|||
CONCURRENT_VIOLATION_SCORE: '0',
|
||||
MESSAGE_VIOLATION_SCORE: '0',
|
||||
NON_BROWSER_VIOLATION_SCORE: '0',
|
||||
FORK_VIOLATION_SCORE: '0',
|
||||
IMPORT_VIOLATION_SCORE: '0',
|
||||
TTS_VIOLATION_SCORE: '0',
|
||||
STT_VIOLATION_SCORE: '0',
|
||||
FILE_UPLOAD_VIOLATION_SCORE: '0',
|
||||
RESET_PASSWORD_VIOLATION_SCORE: '0',
|
||||
VERIFY_EMAIL_VIOLATION_SCORE: '0',
|
||||
TOOL_CALL_VIOLATION_SCORE: '0',
|
||||
CONVO_ACCESS_VIOLATION_SCORE: '0',
|
||||
ILLEGAL_MODEL_REQ_SCORE: '0',
|
||||
LOGIN_MAX: '20',
|
||||
LOGIN_WINDOW: '1',
|
||||
|
|
|
@ -26,6 +26,15 @@ const config: PlaywrightTestConfig = {
|
|||
CONCURRENT_VIOLATION_SCORE: '0',
|
||||
MESSAGE_VIOLATION_SCORE: '0',
|
||||
NON_BROWSER_VIOLATION_SCORE: '0',
|
||||
FORK_VIOLATION_SCORE: '0',
|
||||
IMPORT_VIOLATION_SCORE: '0',
|
||||
TTS_VIOLATION_SCORE: '0',
|
||||
STT_VIOLATION_SCORE: '0',
|
||||
FILE_UPLOAD_VIOLATION_SCORE: '0',
|
||||
RESET_PASSWORD_VIOLATION_SCORE: '0',
|
||||
VERIFY_EMAIL_VIOLATION_SCORE: '0',
|
||||
TOOL_CALL_VIOLATION_SCORE: '0',
|
||||
CONVO_ACCESS_VIOLATION_SCORE: '0',
|
||||
ILLEGAL_MODEL_REQ_SCORE: '0',
|
||||
LOGIN_MAX: '20',
|
||||
LOGIN_WINDOW: '1',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue