mirror of
https://github.com/formbricks/formbricks.git
synced 2026-03-04 18:28:54 -06:00
fix(sdk): add userId length limit to mitigate DoS attack risk (#7378)
Co-authored-by: Matti Nannt <matti@formbricks.com>
This commit is contained in:
@@ -151,6 +151,40 @@ describe("user.ts", () => {
|
||||
expect(mockUpdateQueue.updateUserId).toHaveBeenCalledWith(mockUserId);
|
||||
expect(mockUpdateQueue.processUpdates).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("should reject userId longer than 255 characters and not send updates", async () => {
|
||||
const mockConfig = {
|
||||
get: vi.fn().mockReturnValue({
|
||||
user: {
|
||||
data: {
|
||||
userId: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
const mockLogger = {
|
||||
debug: vi.fn(),
|
||||
error: vi.fn(),
|
||||
};
|
||||
|
||||
const mockUpdateQueue = {
|
||||
updateUserId: vi.fn(),
|
||||
processUpdates: vi.fn(),
|
||||
};
|
||||
|
||||
getInstanceConfigMock.mockReturnValue(mockConfig as unknown as Config);
|
||||
getInstanceLoggerMock.mockReturnValue(mockLogger as unknown as Logger);
|
||||
getInstanceUpdateQueueMock.mockReturnValue(mockUpdateQueue as unknown as UpdateQueue);
|
||||
|
||||
const longId = "a".repeat(256);
|
||||
const result = await setUserId(longId);
|
||||
|
||||
expect(result.ok).toBe(true);
|
||||
expect(mockLogger.error).toHaveBeenCalledWith("UserId exceeds maximum length of 255 characters");
|
||||
expect(mockUpdateQueue.updateUserId).not.toHaveBeenCalled();
|
||||
expect(mockUpdateQueue.processUpdates).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("logout", () => {
|
||||
|
||||
@@ -26,6 +26,12 @@ export const setUserId = async (userId: string): Promise<Result<void, ApiErrorRe
|
||||
tearDown();
|
||||
}
|
||||
|
||||
const MAX_USER_ID_LENGTH = 255;
|
||||
if (userId.length > MAX_USER_ID_LENGTH) {
|
||||
logger.error(`UserId exceeds maximum length of ${String(MAX_USER_ID_LENGTH)} characters`);
|
||||
return okVoid();
|
||||
}
|
||||
|
||||
updateQueue.updateUserId(userId);
|
||||
void updateQueue.processUpdates();
|
||||
return okVoid();
|
||||
|
||||
@@ -13,7 +13,12 @@ export type TDisplay = z.infer<typeof ZDisplay>;
|
||||
export const ZDisplayCreateInput = z.object({
|
||||
environmentId: z.string().cuid2(),
|
||||
surveyId: z.string().cuid2(),
|
||||
userId: z.string().optional(),
|
||||
userId: z
|
||||
.string()
|
||||
.max(255, {
|
||||
message: "User ID cannot exceed 255 characters",
|
||||
})
|
||||
.optional(),
|
||||
responseId: z.string().cuid2().optional(),
|
||||
});
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ export type TJsPersonState = z.infer<typeof ZJsPersonState>;
|
||||
|
||||
export const ZJsUserIdentifyInput = z.object({
|
||||
environmentId: z.string().cuid(),
|
||||
userId: z.string(),
|
||||
userId: z.string().max(255),
|
||||
});
|
||||
|
||||
export type TJsPersonIdentifyInput = z.infer<typeof ZJsUserIdentifyInput>;
|
||||
@@ -145,7 +145,7 @@ export const ZJsEnvironmentSyncParams = z.object({
|
||||
export type TJsEnvironmentSyncParams = z.infer<typeof ZJsEnvironmentSyncParams>;
|
||||
|
||||
export const ZJsPersonSyncParams = ZJsEnvironmentSyncParams.extend({
|
||||
userId: z.string(),
|
||||
userId: z.string().max(255),
|
||||
attributes: ZAttributes.optional(),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user