Skip to content

Commit dc07f40

Browse files
christopherholland-workdaychristopherholland-workdayyau-wd
authored
Fix IDOR in Evaluators and Evaluations Endpoints (#6050)
* Fix IDOR in Evaluators and Evaluations Endpoints * chore(services/evaluations & EvaluatorDTO): replace explicit field assignment with stripProtectedFields --------- Co-authored-by: christopherholland-workday <christopher.holland+evisort@workday.com> Co-authored-by: yau-wd <yau.ong@workday.com>
1 parent 4fc67b1 commit dc07f40

4 files changed

Lines changed: 21 additions & 16 deletions

File tree

packages/server/src/Interface.Evaluation.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Evaluation Related Interfaces
22
import { Evaluator } from './database/entities/Evaluator'
3+
import { stripProtectedFields } from './utils/stripProtectedFields'
34

45
export interface IDataset {
56
id: string
@@ -82,7 +83,7 @@ export class EvaluatorDTO {
8283

8384
static toEntity(body: any): Evaluator {
8485
const newDs = new Evaluator()
85-
Object.assign(newDs, body)
86+
Object.assign(newDs, stripProtectedFields(body))
8687
let config: any = {}
8788
if (body.type === 'llm') {
8889
config = {

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

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
1-
import { StatusCodes } from 'http-status-codes'
21
import { EvaluationRunner, ICommonObject } from 'flowise-components'
3-
import { getRunningExpressApp } from '../../utils/getRunningExpressApp'
4-
import { InternalFlowiseError } from '../../errors/internalFlowiseError'
5-
import { getErrorMessage } from '../../errors/utils'
2+
import { StatusCodes } from 'http-status-codes'
3+
import { In } from 'typeorm'
4+
import { v4 as uuidv4 } from 'uuid'
5+
import { ApiKey } from '../../database/entities/ApiKey'
6+
import { Assistant } from '../../database/entities/Assistant'
7+
import { ChatFlow } from '../../database/entities/ChatFlow'
8+
import { Credential } from '../../database/entities/Credential'
69
import { Dataset } from '../../database/entities/Dataset'
710
import { DatasetRow } from '../../database/entities/DatasetRow'
811
import { Evaluation } from '../../database/entities/Evaluation'
9-
import { EvaluationStatus, IEvaluationResult } from '../../Interface'
1012
import { EvaluationRun } from '../../database/entities/EvaluationRun'
11-
import { Credential } from '../../database/entities/Credential'
12-
import { ApiKey } from '../../database/entities/ApiKey'
13-
import { ChatFlow } from '../../database/entities/ChatFlow'
14-
import { getAppVersion } from '../../utils'
15-
import { In } from 'typeorm'
1613
import { getWorkspaceSearchOptions } from '../../enterprise/utils/ControllerServiceUtils'
17-
import { v4 as uuidv4 } from 'uuid'
14+
import { InternalFlowiseError } from '../../errors/internalFlowiseError'
15+
import { getErrorMessage } from '../../errors/utils'
16+
import { EvaluationStatus, IEvaluationResult } from '../../Interface'
17+
import { getAppVersion } from '../../utils'
18+
import { getRunningExpressApp } from '../../utils/getRunningExpressApp'
19+
import { stripProtectedFields } from '../../utils/stripProtectedFields'
20+
import evaluatorsService from '../evaluator'
1821
import { calculateCost, formatCost } from './CostCalculator'
1922
import { runAdditionalEvaluators } from './EvaluatorRunner'
20-
import evaluatorsService from '../evaluator'
2123
import { LLMEvaluationRunner } from './LLMEvaluationRunner'
22-
import { Assistant } from '../../database/entities/Assistant'
2324

2425
const runAgain = async (id: string, baseURL: string, orgId: string, workspaceId: string) => {
2526
try {
@@ -66,7 +67,8 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str
6667
try {
6768
const appServer = getRunningExpressApp()
6869
const newEval = new Evaluation()
69-
Object.assign(newEval, body)
70+
Object.assign(newEval, stripProtectedFields(body))
71+
newEval.workspaceId = workspaceId
7072
newEval.status = EvaluationStatus.PENDING
7173

7274
const row = appServer.AppDataSource.getRepository(Evaluation).create(newEval)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const createEvaluator = async (body: any) => {
5353
try {
5454
const appServer = getRunningExpressApp()
5555
const newDs = EvaluatorDTO.toEntity(body)
56+
newDs.workspaceId = body.workspaceId
5657

5758
const evaluator = appServer.AppDataSource.getRepository(Evaluator).create(newDs)
5859
const result = await appServer.AppDataSource.getRepository(Evaluator).save(evaluator)
@@ -78,6 +79,7 @@ const updateEvaluator = async (id: string, body: any, workspaceId: string) => {
7879

7980
const updateEvaluator = EvaluatorDTO.toEntity(body)
8081
updateEvaluator.id = id
82+
updateEvaluator.workspaceId = workspaceId
8183
appServer.AppDataSource.getRepository(Evaluator).merge(evaluator, updateEvaluator)
8284
const result = await appServer.AppDataSource.getRepository(Evaluator).save(evaluator)
8385
return EvaluatorDTO.fromEntity(result)

packages/server/src/utils/stripProtectedFields.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Fields that are managed exclusively by the server and must never be
33
* overwritten by user-supplied request bodies.
44
*/
5-
export const PROTECTED_FIELDS = ['id', 'createdDate', 'updatedDate', 'workspaceId', 'organizationId'] as const
5+
export const PROTECTED_FIELDS = ['id', 'createdDate', 'updatedDate', 'runDate', 'workspaceId', 'organizationId'] as const
66

77
export type ProtectedField = (typeof PROTECTED_FIELDS)[number]
88

0 commit comments

Comments
 (0)