Skip to content

Commit 06dc0e1

Browse files
christopherholland-workdaychristopherholland-workdayyau-wd
authored
Fix IDOR Takeover in PUT /api/v1/user (#5986)
Co-authored-by: christopherholland-workday <christopher.holland+evisort@workday.com> Co-authored-by: yau-wd <yau.ong@workday.com>
1 parent 7dc48ad commit 06dc0e1

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

packages/server/src/enterprise/controllers/user.controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ export class UserController {
5656
if (!currentUser) {
5757
throw new InternalFlowiseError(StatusCodes.UNAUTHORIZED, UserErrorMessage.USER_NOT_FOUND)
5858
}
59-
const { id } = req.body
59+
const { id, name, oldPassword, newPassword, confirmPassword } = req.body
6060
if (currentUser.id !== id) {
6161
throw new InternalFlowiseError(StatusCodes.FORBIDDEN, UserErrorMessage.USER_NOT_FOUND)
6262
}
63-
const user = await userService.updateUser(req.body)
63+
const user = await userService.updateUser({ id, name, updatedBy: currentUser.id, oldPassword, newPassword, confirmPassword })
6464
return res.status(StatusCodes.OK).json(user)
6565
} catch (error) {
6666
next(error)

packages/server/src/enterprise/services/user.service.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,10 @@ export class UserService {
150150
if (!updateUserData) throw new InternalFlowiseError(StatusCodes.NOT_FOUND, UserErrorMessage.USER_NOT_FOUND)
151151
}
152152

153-
newUserData.createdBy = oldUserData.createdBy
154-
155153
if (newUserData.name) {
156154
this.validateUserName(newUserData.name)
157155
}
158156

159-
if (newUserData.status) {
160-
this.validateUserStatus(newUserData.status)
161-
}
162-
163157
if (newUserData.oldPassword && newUserData.newPassword && newUserData.confirmPassword) {
164158
if (!oldUserData.credential) {
165159
throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, UserErrorMessage.INVALID_USER_CREDENTIAL)
@@ -176,7 +170,23 @@ export class UserService {
176170
newUserData.tokenExpiry = undefined
177171
}
178172

179-
updatedUser = queryRunner.manager.merge(User, oldUserData, newUserData)
173+
const safePatch: Partial<User> = {
174+
createdBy: oldUserData.createdBy // always preserve from DB
175+
}
176+
177+
if (newUserData.name) {
178+
safePatch.name = newUserData.name
179+
}
180+
181+
safePatch.updatedBy = newUserData.updatedBy // always set (controller forces req.user.id)
182+
if (newUserData.oldPassword && newUserData.newPassword && newUserData.confirmPassword) {
183+
// credential/tempToken/tokenExpiry were set by the validated workflow above
184+
safePatch.credential = newUserData.credential
185+
safePatch.tempToken = newUserData.tempToken
186+
safePatch.tokenExpiry = newUserData.tokenExpiry
187+
}
188+
189+
updatedUser = queryRunner.manager.merge(User, oldUserData, safePatch)
180190
await queryRunner.startTransaction()
181191
await this.saveUser(updatedUser, queryRunner)
182192
await queryRunner.commitTransaction()

0 commit comments

Comments
 (0)