fix(security): harden input validation schemas and fix SSR sanitize bypass

- blueprint rolePresets: cap array at 100 items to prevent storage abuse
- notification CreateManagedNotification: add .max() on title (500),
  body (2000), type (100), entityType/entityId (200), link (1000),
  taskAction (200)
- settings: add .max() on all string config fields; add regex allowlist
  (/^[a-zA-Z0-9._-]+$/) on model name fields (geminiModel,
  azureDalleDeployment, azureOpenAiDeployment) to prevent path manipulation
- sanitizeHtml: fix SSR bypass — server-side branch now strips HTML tags
  instead of returning the raw string unchanged

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-09 21:38:16 +02:00
parent df191d1e03
commit 1833182e90
4 changed files with 25 additions and 22 deletions
@@ -180,16 +180,16 @@ export const MarkNotificationReadInputSchema = z.object({
export const CreateManagedNotificationInputSchema = z.object({
userId: z.string(),
type: z.string(),
title: z.string(),
body: z.string().optional(),
entityId: z.string().optional(),
entityType: z.string().optional(),
type: z.string().max(100),
title: z.string().max(500),
body: z.string().max(2000).optional(),
entityId: z.string().max(200).optional(),
entityType: z.string().max(200).optional(),
category: categoryEnum.optional(),
priority: priorityEnum.optional(),
link: z.string().optional(),
link: z.string().max(1000).optional(),
taskStatus: taskStatusEnum.optional(),
taskAction: z.string().optional(),
taskAction: z.string().max(200).optional(),
assigneeId: z.string().optional(),
dueDate: z.date().optional(),
channel: channelEnum.optional(),