Fix Chatflow Query to Protect Against Cross-Workspace Chatflow Disclosure (#6043)

Co-authored-by: christopherholland-workday <[email protected]>
This commit is contained in:
christopherholland-workday
2026-03-24 08:59:23 -07:00
committed by GitHub
co-authored by christopherholland-workday
parent 97b96f60d3
commit f7d86912fa
2 changed files with 12 additions and 7 deletions
@@ -99,7 +99,7 @@ const getChatflowByApiKey = async (req: Request, res: Response, next: NextFuncti
if (!apikey) {
return res.status(401).send('Unauthorized')
}
const apiResponse = await chatflowsService.getChatflowByApiKey(apikey.id, req.query.keyonly)
const apiResponse = await chatflowsService.getChatflowByApiKey(apikey.id, apikey.workspaceId, req.query.keyonly)
return res.json(apiResponse)
} catch (error) {
next(error)
@@ -1,6 +1,6 @@
import { ICommonObject, removeFolderFromStorage } from 'flowise-components'
import { StatusCodes } from 'http-status-codes'
import { In } from 'typeorm'
import { Brackets, In } from 'typeorm'
import { validate as isValidUUID } from 'uuid'
import { ChatflowType, IReactFlowObject } from '../../Interface'
import { FLOWISE_COUNTER_STATUS, FLOWISE_METRIC_COUNTERS } from '../../Interface.Metrics'
@@ -220,16 +220,21 @@ const getAllChatflowsCount = async (type?: ChatflowType, workspaceId?: string):
}
}
const getChatflowByApiKey = async (apiKeyId: string, keyonly?: unknown): Promise<any> => {
const getChatflowByApiKey = async (apiKeyId: string, workspaceId: string, keyonly?: unknown): Promise<any> => {
try {
// Here we only get chatflows that are bounded by the apikeyid and chatflows that are not bounded by any apikey
const appServer = getRunningExpressApp()
let query = appServer.AppDataSource.getRepository(ChatFlow)
.createQueryBuilder('cf')
.where('cf.apikeyid = :apikeyid', { apikeyid: apiKeyId })
if (keyonly === undefined) {
query = query.orWhere('cf.apikeyid IS NULL').orWhere('cf.apikeyid = ""')
}
.where('cf.workspaceId = :workspaceId', { workspaceId })
.andWhere(
new Brackets((qb) => {
qb.where('cf.apikeyid = :apikeyid', { apikeyid: apiKeyId })
if (keyonly === undefined) {
qb.orWhere('cf.apikeyid IS NULL').orWhere('cf.apikeyid = ""')
}
})
)
const dbResponse = await query.orderBy('cf.name', 'ASC').getMany()
if (dbResponse.length < 1) {