mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 14:16:12 +00:00
security: fix rate limiting, error message leaks, decrypt crash, key preview
- H1: Add checkRateLimit to OAuth authorize/callback/disconnect + admin AI settings
- H2: Fix decrypt("") crash in provider.ts onTokenRefresh by using decrypt() directly
- H3: Truncate error messages in codex-oauth, codex-client, openai-client to prevent leaking upstream response bodies
- M5: Fix keyPreview to show last 4 chars of decrypted key instead of ciphertext prefix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
50911ad801
commit
d3149170cd
8 files changed
+33
-20
No files matched your search
@@ -3,7 +3,8 @@ import { apiHandler, requireAdmin, HttpError } from "@/lib/api-handler";
|
||||
import { prisma } from "@/lib/db";
|
||||
import { auditLog } from "@/lib/auth/audit";
|
||||
import { apiSuccess, getClientIp, safeJson } from "@/lib/api-response";
|
||||
import { encrypt } from "@/lib/crypto";
|
||||
import { encrypt, decrypt } from "@/lib/crypto";
|
||||
import { checkRateLimit } from "@/lib/rate-limit";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
@@ -22,8 +23,8 @@ export const GET = apiHandler(async () => {
|
||||
|
||||
return apiSuccess({
|
||||
hasKey,
|
||||
keyPreview: hasKey && settings?.adminAiKeyEncrypted
|
||||
? `${settings.adminAiKeyEncrypted.slice(0, 7)}...`
|
||||
keyPreview: settings?.adminAiKeyEncrypted
|
||||
? `...${decrypt(settings.adminAiKeyEncrypted).slice(-4)}`
|
||||
: null,
|
||||
model,
|
||||
baseUrl,
|
||||
@@ -34,6 +35,9 @@ export const PUT = apiHandler(async (request: NextRequest) => {
|
||||
const { user } = await requireAdmin();
|
||||
annotate({ action: { name: "admin.ai-settings.update" } });
|
||||
|
||||
const rl = await checkRateLimit("admin-ai-settings", 10, 60_000);
|
||||
if (!rl.allowed) throw new HttpError(429, "Too many requests");
|
||||
|
||||
const { data: body, error: jsonError } = await safeJson(request);
|
||||
if (jsonError) return jsonError;
|
||||
|
||||
@@ -94,8 +98,8 @@ export const PUT = apiHandler(async (request: NextRequest) => {
|
||||
|
||||
return apiSuccess({
|
||||
hasKey,
|
||||
keyPreview: hasKey && settings.adminAiKeyEncrypted
|
||||
? `${settings.adminAiKeyEncrypted.slice(0, 7)}...`
|
||||
keyPreview: settings.adminAiKeyEncrypted
|
||||
? `...${decrypt(settings.adminAiKeyEncrypted).slice(-4)}`
|
||||
: null,
|
||||
model: settings.adminAiModel,
|
||||
baseUrl: settings.adminAiBaseUrl,
|
||||
|
||||
Reference in new issue
Block a user