@@ -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+
1318export 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 ] ) ) {
0 commit comments