code security

This commit is contained in:
overcuriousity
2025-07-19 15:30:12 +02:00
parent e29d10cf81
commit 20e9e5e5ae
8 changed files with 112 additions and 38 deletions

View File

@@ -16,31 +16,24 @@ function getEnv(key: string): string {
}
const AI_MODEL = getEnv('AI_MODEL');
// Rate limiting store (in production, use Redis)
const rateLimitStore = new Map<string, { count: number; resetTime: number }>();
const RATE_LIMIT_WINDOW = 60 * 1000; // 1 minute
const RATE_LIMIT_MAX = 10; // 10 requests per minute per user
// Input validation and sanitization
function sanitizeInput(input: string): string {
// Remove potential prompt injection patterns
const dangerous = [
/ignore\s+previous\s+instructions?/gi,
/new\s+instructions?:/gi,
/system\s*:/gi,
/assistant\s*:/gi,
/human\s*:/gi,
/<\s*\/?system\s*>/gi,
/```\s*system/gi,
];
// Remove any content that looks like system instructions
let sanitized = input
.replace(/```[\s\S]*?```/g, '[CODE_BLOCK_REMOVED]') // Remove code blocks
.replace(/\<\/?[^>]+(>|$)/g, '') // Remove HTML tags
.replace(/\b(system|assistant|user)\s*[:]/gi, '[ROLE_REMOVED]')
.replace(/\b(ignore|forget|disregard)\s+(previous|all|your)\s+(instructions?|context|rules?)/gi, '[INSTRUCTION_REMOVED]')
.trim();
let sanitized = input.trim();
dangerous.forEach(pattern => {
sanitized = sanitized.replace(pattern, '[FILTERED]');
});
// Limit length and remove excessive whitespace
sanitized = sanitized.slice(0, 2000).replace(/\s+/g, ' ');
// Limit length
return sanitized.slice(0, 2000);
return sanitized;
}
// Strip markdown code blocks from AI response
@@ -70,6 +63,17 @@ function checkRateLimit(userId: string): boolean {
return true;
}
function cleanupExpiredRateLimits() {
const now = Date.now();
for (const [userId, limit] of rateLimitStore.entries()) {
if (now > limit.resetTime) {
rateLimitStore.delete(userId);
}
}
}
setInterval(cleanupExpiredRateLimits, 5 * 60 * 1000);
// Load tools database
async function loadToolsDatabase() {
try {

View File

@@ -10,11 +10,13 @@ import {
export const GET: APIRoute = async ({ url, request }) => {
try {
// Debug: multiple ways to access URL parameters
console.log('Full URL:', url.toString());
console.log('URL pathname:', url.pathname);
console.log('URL search:', url.search);
console.log('URL searchParams:', url.searchParams.toString());
if (process.env.NODE_ENV === 'development') {
console.log('Auth callback processing...');
console.log('Full URL:', url.toString());
console.log('URL pathname:', url.pathname);
console.log('URL search:', url.search);
console.log('URL searchParams:', url.searchParams.toString());
}
// Try different ways to get parameters
const allParams = Object.fromEntries(url.searchParams.entries());

14
src/pages/api/health.ts Normal file
View File

@@ -0,0 +1,14 @@
import type { APIRoute } from 'astro';
export const prerender = false;
export const GET: APIRoute = async () => {
return new Response(JSON.stringify({
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime()
}), {
status: 200,
headers: { 'Content-Type': 'application/json' }
});
};