Skip to content

Commit d51d18a

Browse files
author
christopherholland-workday
committed
Revert "Add protections for loop-bound injections"
This reverts commit c75f4fc.
1 parent 4b7e6d6 commit d51d18a

3 files changed

Lines changed: 58 additions & 0 deletions

File tree

packages/components/evaluation/EvaluationRunner.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,21 @@ export class EvaluationRunner {
9494
throw new Error('chatflowId must be a valid array')
9595
}
9696

97+
const MAX_CHATFLOWS = 1000
98+
if (chatflowIds.length > MAX_CHATFLOWS) {
99+
throw new Error(`Cannot evaluate more than ${MAX_CHATFLOWS} chatflows at once`)
100+
}
101+
97102
// Validate dataset.rows is an actual array to prevent DoS attacks
98103
if (!data.dataset || !Array.isArray(data.dataset.rows)) {
99104
throw new Error('dataset.rows must be a valid array')
100105
}
101106

107+
const MAX_ROWS = 1000
108+
if (data.dataset.rows.length > MAX_ROWS) {
109+
throw new Error(`Dataset cannot exceed ${MAX_ROWS} rows`)
110+
}
111+
102112
const returnData: ICommonObject = {}
103113
returnData.evaluationId = data.evaluationId
104114
returnData.runDate = new Date()

packages/server/src/services/evaluations/EvaluatorRunner.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ interface EvaluatorReturnType {
1010
result: 'Pass' | 'Fail' | 'Error'
1111
}
1212

13+
// Limit maximum array sizes to prevent DoS attacks
14+
const MAX_OUTPUTS = 10000
15+
const MAX_EVALUATORS = 1000
16+
const MAX_SPLIT_VALUES = 1000
17+
1318
export const runAdditionalEvaluators = async (
1419
metricsArray: ICommonObject[],
1520
actualOutputArray: string[],
@@ -22,6 +27,14 @@ export const runAdditionalEvaluators = async (
2227
throw new Error('Invalid input: expected arrays')
2328
}
2429

30+
if (actualOutputArray.length > MAX_OUTPUTS) {
31+
throw new Error(`Too many outputs: maximum allowed is ${MAX_OUTPUTS}`)
32+
}
33+
34+
if (selectedEvaluators.length > MAX_EVALUATORS) {
35+
throw new Error(`Too many evaluators: maximum allowed is ${MAX_EVALUATORS}`)
36+
}
37+
2538
const evaluationResults: any[] = []
2639
const evaluatorDict: any = {}
2740

@@ -108,6 +121,10 @@ export const runAdditionalEvaluators = async (
108121
case 'ContainsAny':
109122
passed = false
110123
splitValues = value.split(',').map((v) => v.trim().toLowerCase()) // Split, trim, and convert to lowercase
124+
// Limit split values to prevent unbounded iteration
125+
if (splitValues.length > MAX_SPLIT_VALUES) {
126+
throw new Error(`Too many split values: maximum allowed is ${MAX_SPLIT_VALUES}`)
127+
}
111128

112129
for (let i = 0; i < splitValues.length; i++) {
113130
if (actualOutput.includes(splitValues[i])) {
@@ -123,6 +140,10 @@ export const runAdditionalEvaluators = async (
123140
case 'ContainsAll':
124141
passed = true
125142
splitValues = value.split(',').map((v) => v.trim().toLowerCase()) // Split, trim, and convert to lowercase
143+
// Limit split values to prevent unbounded iteration
144+
if (splitValues.length > MAX_SPLIT_VALUES) {
145+
throw new Error(`Too many split values: maximum allowed is ${MAX_SPLIT_VALUES}`)
146+
}
126147

127148
for (let i = 0; i < splitValues.length; i++) {
128149
if (!actualOutput.includes(splitValues[i])) {
@@ -138,6 +159,10 @@ export const runAdditionalEvaluators = async (
138159
case 'DoesNotContainAny':
139160
passed = true
140161
splitValues = value.split(',').map((v) => v.trim().toLowerCase()) // Split, trim, and convert to lowercase
162+
// Limit split values to prevent unbounded iteration
163+
if (splitValues.length > MAX_SPLIT_VALUES) {
164+
throw new Error(`Too many split values: maximum allowed is ${MAX_SPLIT_VALUES}`)
165+
}
141166

142167
for (let i = 0; i < splitValues.length; i++) {
143168
if (actualOutput.includes(splitValues[i])) {
@@ -153,6 +178,10 @@ export const runAdditionalEvaluators = async (
153178
case 'DoesNotContainAll':
154179
passed = true
155180
splitValues = value.split(',').map((v) => v.trim().toLowerCase()) // Split, trim, and convert to lowercase
181+
// Limit split values to prevent unbounded iteration
182+
if (splitValues.length > MAX_SPLIT_VALUES) {
183+
throw new Error(`Too many split values: maximum allowed is ${MAX_SPLIT_VALUES}`)
184+
}
156185

157186
for (let i = 0; i < splitValues.length; i++) {
158187
if (actualOutput.includes(splitValues[i])) {

packages/server/src/services/evaluations/index.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,21 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str
7878
throw new Error('chatflowType must be a valid array')
7979
}
8080

81+
const MAX_CHATFLOW_TYPES = 1000
82+
if (chatflowTypes.length > MAX_CHATFLOW_TYPES) {
83+
throw new Error(`Cannot evaluate more than ${MAX_CHATFLOW_TYPES} chatflow types at once`)
84+
}
85+
8186
const simpleEvaluators = body.selectedSimpleEvaluators.length > 0 ? JSON.parse(body.selectedSimpleEvaluators) : []
8287
if (!Array.isArray(simpleEvaluators)) {
8388
throw new Error('selectedSimpleEvaluators must be a valid array')
8489
}
8590

91+
const MAX_EVALUATORS = 1000
92+
if (simpleEvaluators.length > MAX_EVALUATORS) {
93+
throw new Error(`Cannot use more than ${MAX_EVALUATORS} simple evaluators at once`)
94+
}
95+
8696
const additionalConfig: ICommonObject = {
8797
chatflowTypes: chatflowTypes,
8898
datasetAsOneConversation: body.datasetAsOneConversation,
@@ -95,6 +105,10 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str
95105
throw new Error('selectedLLMEvaluators must be a valid array')
96106
}
97107

108+
if (lLMEvaluators.length > MAX_EVALUATORS) {
109+
throw new Error(`Cannot use more than ${MAX_EVALUATORS} LLM evaluators at once`)
110+
}
111+
98112
additionalConfig.lLMEvaluators = lLMEvaluators
99113
additionalConfig.llmConfig = {
100114
credentialId: body.credentialId,
@@ -145,6 +159,11 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str
145159
throw new Error('chatflowId must be a valid array')
146160
}
147161

162+
const MAX_CHATFLOWS_EVAL = 100
163+
if (chatflowIds.length > MAX_CHATFLOWS_EVAL) {
164+
throw new Error(`Cannot evaluate more than ${MAX_CHATFLOWS_EVAL} chatflows at once`)
165+
}
166+
148167
for (let i = 0; i < chatflowIds.length; i++) {
149168
const chatflowId = chatflowIds[i]
150169
const cFlow = await appServer.AppDataSource.getRepository(ChatFlow).findOneBy({

0 commit comments

Comments
 (0)