diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..4ae8a61 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,27 @@ +# Security Policy + +## Reporting a Vulnerability + +If you discover a security vulnerability in CapaKraken, please report it responsibly. + +**Do not** open a public GitHub issue for security vulnerabilities. + +Instead, please email the maintainer directly with: + +1. A description of the vulnerability +2. Steps to reproduce +3. Potential impact assessment + +We will acknowledge receipt within 48 hours and provide a timeline for resolution. + +## Supported Versions + +Only the latest version on the `main` branch receives security updates. + +## Security Practices + +- Dependencies are audited nightly via `pnpm audit` and on every CI run +- Authentication uses Argon2-based password hashing via Auth.js v5 +- Rate limiting is enforced on all API endpoints with Redis-backed counters +- All database mutations use parameterized queries via Prisma (no raw SQL) +- Session tokens are rotated on password change diff --git a/packages/api/src/router/blueprint-procedure-support.ts b/packages/api/src/router/blueprint-procedure-support.ts index 3a7ef43..e819d93 100644 --- a/packages/api/src/router/blueprint-procedure-support.ts +++ b/packages/api/src/router/blueprint-procedure-support.ts @@ -1,4 +1,9 @@ -import { BlueprintTarget, CreateBlueprintSchema, UpdateBlueprintSchema } from "@capakraken/shared"; +import { + BlueprintTarget, + CreateBlueprintSchema, + RolePresetsSchema, + UpdateBlueprintSchema, +} from "@capakraken/shared"; import { z } from "zod"; import { findUniqueOrThrow } from "../db/helpers.js"; import { makeAuditLogger } from "../lib/audit-helpers.js"; @@ -54,7 +59,7 @@ export const blueprintUpdateInputSchema = z.object({ export const blueprintRolePresetsInputSchema = z.object({ id: z.string(), - rolePresets: z.array(z.unknown()).max(100), + rolePresets: RolePresetsSchema.max(100), }); export const blueprintBatchDeleteInputSchema = z.object({ diff --git a/packages/api/src/router/blueprint-support.ts b/packages/api/src/router/blueprint-support.ts index ed9f592..c8abb41 100644 --- a/packages/api/src/router/blueprint-support.ts +++ b/packages/api/src/router/blueprint-support.ts @@ -30,23 +30,23 @@ export async function findBlueprintByIdentifier( ): Promise { const normalizedIdentifier = identifier.trim(); - let blueprint = await db.blueprint.findUnique({ + let blueprint = (await db.blueprint.findUnique({ where: { id: normalizedIdentifier }, ...extraArgs, - }) as TBlueprint | null; + })) as TBlueprint | null; if (!blueprint) { - blueprint = await db.blueprint.findFirst({ + blueprint = (await db.blueprint.findFirst({ where: { name: { equals: normalizedIdentifier, mode: "insensitive" } }, ...extraArgs, - }) as TBlueprint | null; + })) as TBlueprint | null; } if (!blueprint) { - blueprint = await db.blueprint.findFirst({ + blueprint = (await db.blueprint.findFirst({ where: { name: { contains: normalizedIdentifier, mode: "insensitive" } }, ...extraArgs, - }) as TBlueprint | null; + })) as TBlueprint | null; } if (!blueprint) { @@ -91,7 +91,7 @@ export function buildBlueprintUpdateData( } export function buildBlueprintRolePresetsUpdateData( - rolePresets: unknown[], + rolePresets: readonly Record[], ): Prisma.BlueprintUncheckedUpdateInput { return { rolePresets: rolePresets as unknown as Prisma.InputJsonValue,