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:
bharath kumar
2026-03-03 14:40:01 +05:30
committed by GitHub
parent e4aa66b067
commit d939263472
4 changed files with 48 additions and 3 deletions

View File

@@ -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", () => {

View File

@@ -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();

View File

@@ -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(),
});

View File

@@ -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(),
});