From a725461340559d69e548e32825046ac013fe4d0c Mon Sep 17 00:00:00 2001 From: waleedcodes <110061477+waleedcodes@users.noreply.github.com> Date: Fri, 9 Oct 2026 21:24:49 +0500 Subject: [PATCH 1/3] test(risk): test SQL injection and hardcoded secret detectors --- tests/riskEngine.test.ts | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/riskEngine.test.ts diff --git a/tests/riskEngine.test.ts b/tests/riskEngine.test.ts new file mode 100644 index 0000000..8a7efa4 --- /dev/null +++ b/tests/riskEngine.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest'; +import { RiskEngine } from '../src/rules/riskEngine'; + +describe('RiskEngine', () => { + it('should detect SQL injection via template literals with evidence', () => { + const code = ` +export async function queryUser(id: string) { + const result = await db.query(\`SELECT * FROM users WHERE id = '\${id}'\`); + return result; +} +`; + const findings = RiskEngine.analyzeFile('/src/db.ts', code); + const sqlRisk = findings.find((f) => f.ruleId === 'PC-SEC-001'); + expect(sqlRisk).toBeDefined(); + expect(sqlRisk?.severity).toBe('HIGH'); + expect(sqlRisk?.evidenceTrace.length).toBeGreaterThan(0); + expect(sqlRisk?.evidenceTrace[0].description).toContain('template literal'); + }); + + it('should detect SQL injection via string concatenation', () => { + const code = ` +export async function findOrders(status: string) { + return pool.query("SELECT * FROM orders WHERE status = '" + status + "'"); +} +`; + const findings = RiskEngine.analyzeFile('/src/orders.ts', code); + const sqlRisk = findings.find((f) => f.ruleId === 'PC-SEC-001'); + expect(sqlRisk).toBeDefined(); + expect(sqlRisk?.title).toContain('String Concatenation'); + }); + + it('should detect hardcoded secrets (AWS and OpenAI keys)', () => { + const code = ` +const awsKey = "AKIAIOSFODNN7EXAMPLE"; +const openaiKey = "sk-1234567890abcdef1234567890abcdef"; +`; + const findings = RiskEngine.analyzeFile('/src/config.ts', code); + expect(findings.some((f) => f.title.includes('AWS Access Key'))).toBe(true); + expect(findings.some((f) => f.title.includes('OpenAI API Secret Key'))).toBe(true); + }); + + it('should detect dangerous eval and child_process exec', () => { + const code = ` +export function runScript(cmd: string) { + return eval(cmd); +} From 0882ca405c37015d928b034e51c6db02181fb70a Mon Sep 17 00:00:00 2001 From: waleedcodes <110061477+waleedcodes@users.noreply.github.com> Date: Fri, 9 Oct 2026 21:24:49 +0500 Subject: [PATCH 2/3] test(risk): test dangerous execution, SSRF, and missing auth rules --- tests/riskEngine.test.ts | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/riskEngine.test.ts b/tests/riskEngine.test.ts index 8a7efa4..a16b56e 100644 --- a/tests/riskEngine.test.ts +++ b/tests/riskEngine.test.ts @@ -44,3 +44,57 @@ const openaiKey = "sk-1234567890abcdef1234567890abcdef"; export function runScript(cmd: string) { return eval(cmd); } +`; + const findings = RiskEngine.analyzeFile('/src/exec.ts', code); + const evalRisk = findings.find((f) => f.ruleId === 'PC-SEC-004'); + expect(evalRisk).toBeDefined(); + expect(evalRisk?.severity).toBe('HIGH'); + }); + + it('should detect SSRF / unvalidated external requests', () => { + const code = ` +export async function proxy(req: any) { + return fetch(req.body.targetUrl); +} +`; + const findings = RiskEngine.analyzeFile('/src/proxy.ts', code); + const ssrfRisk = findings.find((f) => f.ruleId === 'PC-SEC-005'); + expect(ssrfRisk).toBeDefined(); + expect(ssrfRisk?.severity).toBe('MEDIUM'); + }); + + it('should detect missing authorization in API routes accessing DB', () => { + const code = ` +export async function GET(req: Request) { + const orders = await db.order.findMany(); + return Response.json(orders); +} +`; + const findings = RiskEngine.analyzeFile('/app/api/orders/route.ts', code); + const authRisk = findings.find((f) => f.ruleId === 'PC-AUTH-001'); + expect(authRisk).toBeDefined(); + expect(authRisk?.severity).toBe('HIGH'); + expect(authRisk?.title).toContain('Missing Authorization Check'); + }); + + it('should NOT flag API routes that check authentication', () => { + const code = ` +import { auth } from '@/auth'; + +export async function GET(req: Request) { + const session = await auth(); + if (!session) return new Response('Unauthorized', { status: 401 }); + const orders = await db.order.findMany({ where: { userId: session.user.id } }); + return Response.json(orders); +} +`; + const findings = RiskEngine.analyzeFile('/app/api/orders/route.ts', code); + const authRisk = findings.find((f) => f.ruleId === 'PC-AUTH-001'); + expect(authRisk).toBeUndefined(); + }); + + it('should detect unhandled null database results', () => { + const code = ` +export async function getProfile(id: string) { + const user = await db.user.findUnique({ where: { id } }); + return user.email; From 1c09dfa9ef37dbcd8e28f2a768470ce8044f745e Mon Sep 17 00:00:00 2001 From: waleedcodes <110061477+waleedcodes@users.noreply.github.com> Date: Fri, 9 Oct 2026 21:24:49 +0500 Subject: [PATCH 3/3] test(risk): test unhandled null results and optional chaining edge cases --- tests/riskEngine.test.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/riskEngine.test.ts b/tests/riskEngine.test.ts index a16b56e..1c249a4 100644 --- a/tests/riskEngine.test.ts +++ b/tests/riskEngine.test.ts @@ -98,3 +98,37 @@ export async function GET(req: Request) { export async function getProfile(id: string) { const user = await db.user.findUnique({ where: { id } }); return user.email; +} +`; + const findings = RiskEngine.analyzeFile('/src/profile.ts', code); + const nullRisk = findings.find((f) => f.ruleId === 'PC-DATA-001'); + expect(nullRisk).toBeDefined(); + expect(nullRisk?.severity).toBe('MEDIUM'); + expect(nullRisk?.title).toContain('Unhandled Null/Undefined Database Result'); + }); + + it('should NOT flag when null check is present', () => { + const code = ` +export async function getProfile(id: string) { + const user = await db.user.findUnique({ where: { id } }); + if (!user) throw new Error('Not found'); + return user.email; +} +`; + const findings = RiskEngine.analyzeFile('/src/profile.ts', code); + const nullRisk = findings.find((f) => f.ruleId === 'PC-DATA-001'); + expect(nullRisk).toBeUndefined(); + }); + + it('should NOT flag when optional chaining is used', () => { + const code = ` +export async function getProfile(id: string) { + const user = await db.user.findUnique({ where: { id } }); + return user?.email; +} +`; + const findings = RiskEngine.analyzeFile('/src/profile.ts', code); + const nullRisk = findings.find((f) => f.ruleId === 'PC-DATA-001'); + expect(nullRisk).toBeUndefined(); + }); +});