Skip to content

Add protections for loop-bound injections#5773

Merged
christopherholland-workday merged 1 commit intomainfrom
loop-bound-injection
Feb 25, 2026
Merged

Add protections for loop-bound injections#5773
christopherholland-workday merged 1 commit intomainfrom
loop-bound-injection

Conversation

@christopherholland-workday
Copy link
Contributor

Adding checks to prevent DoS due to large loop boundaries.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @christopherholland-workday, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the application's security posture by introducing comprehensive input validation and array size limitations across several key evaluation-related functions. The changes aim to prevent Denial of Service vulnerabilities that could arise from processing unusually large or malformed data inputs, thereby improving the stability and resilience of the evaluation system.

Highlights

  • Denial of Service (DoS) Protections: Implemented robust input validation and size limits for various arrays and lists to prevent potential DoS attacks caused by excessively large inputs.
  • Evaluation Runner Enhancements: Added checks in EvaluationRunner to ensure chatflowIds and dataset.rows are valid arrays and do not exceed predefined maximum lengths (1000 each).
  • Evaluator Runner Input Validation: Introduced size limits for actualOutputArray (10000), selectedEvaluators (1000), and splitValues (1000) within the runAdditionalEvaluators function to safeguard against unbounded iterations.
  • Evaluation Creation Safeguards: Applied validation and size limits for chatflowTypes (1000), simpleEvaluators (1000), lLMEvaluators (1000), and chatflowIds (100) during the creation of evaluations.
Changelog
  • packages/components/evaluation/EvaluationRunner.ts
    • Added array validation for chatflowIds and data.dataset.rows.
    • Introduced maximum length checks for chatflowIds (1000) and data.dataset.rows (1000) to prevent DoS.
  • packages/server/src/services/evaluations/EvaluatorRunner.ts
    • Defined constants MAX_OUTPUTS, MAX_EVALUATORS, and MAX_SPLIT_VALUES.
    • Added validation to ensure actualOutputArray and selectedEvaluators are arrays and do not exceed their respective maximum lengths.
    • Implemented size checks for splitValues (1000) in ContainsAny, ContainsAll, DoesNotContainAny, and DoesNotContainAll evaluation cases.
  • packages/server/src/services/evaluations/index.ts
    • Added array validation for chatflowType, selectedSimpleEvaluators, and selectedLLMEvaluators.
    • Introduced maximum length checks for chatflowTypes (1000), simpleEvaluators (1000), and lLMEvaluators (1000).
    • Added array validation for chatflowId and a maximum length check (100) during evaluation creation.
    • Refactored the passing of simpleEvaluators and lLMEvaluators to use pre-validated values from additionalConfig.
Activity
  • No human activity has occurred on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly enhances the application's resilience against Denial of Service (DoS) attacks by implementing robust input validation for array lengths and types. The introduction of MAX_ constants across EvaluationRunner.ts and EvaluatorRunner.ts, along with the corresponding checks, effectively limits the processing of excessively large inputs. This is a crucial step towards improving the overall security and stability of the evaluation services.

@@ -88,6 +88,27 @@ export class EvaluationRunner {

public async runEvaluations(data: ICommonObject) {
const chatflowIds = JSON.parse(data.chatflowId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The JSON.parse operation can throw an error if data.chatflowId is not a valid JSON string, leading to a generic parsing error. Wrapping this in a try-catch block would allow for a more specific and user-friendly error message, clearly indicating that the input format is incorrect.

Suggested change
const chatflowIds = JSON.parse(data.chatflowId)
let chatflowIds: string[];
try {
chatflowIds = JSON.parse(data.chatflowId);
} catch (e) {
throw new Error('chatflowId must be a valid JSON array string');
}

@@ -103,6 +121,11 @@ export const runAdditionalEvaluators = async (
case 'ContainsAny':
passed = false
splitValues = value.split(',').map((v) => v.trim().toLowerCase()) // Split, trim, and convert to lowercase
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While the MAX_SPLIT_VALUES check is in place, the split and map operations are performed on the entire value string first. If value is extremely long and contains many delimiters, these operations could consume significant memory and CPU before the length check. For extreme edge cases, consider a more memory-efficient way to count or process elements, or validate the raw string length before splitting.

row.average_metrics = JSON.stringify({})

// Parse and validate evaluator arrays to prevent DoS attacks
const chatflowTypes = body.chatflowType ? JSON.parse(body.chatflowType) : []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to other JSON.parse calls, if body.chatflowType is provided but is not a valid JSON string, JSON.parse will throw an error. Implementing a try-catch block here would provide a more precise error message to the user about the expected JSON format.

Suggested change
const chatflowTypes = body.chatflowType ? JSON.parse(body.chatflowType) : []
let chatflowTypes: string[];
try {
chatflowTypes = body.chatflowType ? JSON.parse(body.chatflowType) : [];
} catch (e) {
throw new Error('chatflowType must be a valid JSON array string');
}

throw new Error(`Cannot evaluate more than ${MAX_CHATFLOW_TYPES} chatflow types at once`)
}

const simpleEvaluators = body.selectedSimpleEvaluators.length > 0 ? JSON.parse(body.selectedSimpleEvaluators) : []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To provide a clearer error message in case body.selectedSimpleEvaluators is not a valid JSON string, it's recommended to wrap the JSON.parse call in a try-catch block.

Suggested change
const simpleEvaluators = body.selectedSimpleEvaluators.length > 0 ? JSON.parse(body.selectedSimpleEvaluators) : []
let simpleEvaluators: string[];
try {
simpleEvaluators = body.selectedSimpleEvaluators.length > 0 ? JSON.parse(body.selectedSimpleEvaluators) : [];
} catch (e) {
throw new Error('selectedSimpleEvaluators must be a valid JSON array string');
}


if (body.evaluationType === 'llm') {
additionalConfig.lLMEvaluators = body.selectedLLMEvaluators.length > 0 ? JSON.parse(body.selectedLLMEvaluators) : []
const lLMEvaluators = body.selectedLLMEvaluators.length > 0 ? JSON.parse(body.selectedLLMEvaluators) : []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For improved error handling, consider adding a try-catch block around the JSON.parse call for body.selectedLLMEvaluators. This would allow for a more specific error message if the input is not valid JSON.

            let lLMEvaluators: string[];
            try {
                lLMEvaluators = body.selectedLLMEvaluators.length > 0 ? JSON.parse(body.selectedLLMEvaluators) : [];
            } catch (e) {
                throw new Error('selectedLLMEvaluators must be a valid JSON array string');
            }

@@ -123,6 +153,17 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str
// When chatflow has an APIKey
const apiKeys: { chatflowId: string; apiKey: string }[] = []
const chatflowIds = JSON.parse(body.chatflowId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to other JSON.parse operations, if body.chatflowId is not a valid JSON string, a generic parsing error will occur. A try-catch block would enable a more informative error message for invalid JSON input.

        let chatflowIds: string[];
        try {
            chatflowIds = JSON.parse(body.chatflowId);
        } catch (e) {
            throw new Error('chatflowId must be a valid JSON array string');
        }

@HenryHengZJ
Copy link
Contributor

im not a fan of hardcoding limit to prevent DoS. Since evaluateChatflow function is calling the prediction endpoint, this is essentially the same as DoS-ing /prediction endpoint. IMO, this is more on the infra level protection. Our AWS WAF should already give us some default DoS protection

@christopherholland-workday christopherholland-workday merged commit 7e46279 into main Feb 25, 2026
7 checks passed
@christopherholland-workday
Copy link
Contributor Author

Not sure why this says it was merged, it is not in the history: https://github.com/FlowiseAI/Flowise/pulls?q=is%3Apr+is%3Aclosed

And I did not merge it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants