Fix SQL injection vulnerabilities with parameterized queries and table name whitelist

Co-authored-by: praveentcom <82172535+praveentcom@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-11-19 01:56:44 +00:00
parent 9f6906b423
commit 6bd62cae27
2 changed files with 1043 additions and 10 deletions

View File

@@ -7,6 +7,10 @@ const pool = new Pool({
const TABLE_NAME = process.env.DATABASE_TABLE || 'llm_proxy';
// Validate table name against whitelist to prevent SQL injection
const ALLOWED_TABLES = ['llm_proxy', 'llm_proxy_dev', 'llm_proxy_test'];
const validatedTableName = ALLOWED_TABLES.includes(TABLE_NAME) ? TABLE_NAME : 'llm_proxy';
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const hours = parseInt(searchParams.get('hours') || '24', 10);
@@ -25,10 +29,10 @@ export async function GET(request: NextRequest) {
AVG(response_time) as avg_response_time,
COUNT(DISTINCT model) as unique_models,
COUNT(DISTINCT client_ip) as unique_clients
FROM ${TABLE_NAME}
WHERE timestamp >= NOW() - INTERVAL '${hours} hours'
FROM ${validatedTableName}
WHERE timestamp >= NOW() - INTERVAL '$1 hours'
`;
const summaryResult = await client.query(summaryQuery);
const summaryResult = await client.query(summaryQuery, [hours]);
const summary = summaryResult.rows[0];
// Get recent requests
@@ -45,7 +49,7 @@ export async function GET(request: NextRequest) {
response_status,
client_ip,
stream
FROM ${TABLE_NAME}
FROM ${validatedTableName}
WHERE timestamp >= NOW() - INTERVAL '$1 hours'
ORDER BY timestamp DESC
LIMIT $2
@@ -61,12 +65,12 @@ export async function GET(request: NextRequest) {
SUM(total_tokens) as total_tokens,
SUM(total_cost) as total_cost,
AVG(response_time) as avg_response_time
FROM ${TABLE_NAME}
WHERE timestamp >= NOW() - INTERVAL '${hours} hours'
FROM ${validatedTableName}
WHERE timestamp >= NOW() - INTERVAL '$1 hours'
GROUP BY model
ORDER BY request_count DESC
`;
const modelResult = await client.query(modelQuery);
const modelResult = await client.query(modelQuery, [hours]);
const modelBreakdown = modelResult.rows;
// Get hourly trends
@@ -77,12 +81,12 @@ export async function GET(request: NextRequest) {
SUM(total_tokens) as tokens,
SUM(total_cost) as cost,
AVG(response_time) as avg_response_time
FROM ${TABLE_NAME}
WHERE timestamp >= NOW() - INTERVAL '${hours} hours'
FROM ${validatedTableName}
WHERE timestamp >= NOW() - INTERVAL '$1 hours'
GROUP BY hour
ORDER BY hour ASC
`;
const trendsResult = await client.query(trendsQuery);
const trendsResult = await client.query(trendsQuery, [hours]);
const hourlyTrends = trendsResult.rows;
return NextResponse.json({

1029
dashboard/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff