一、输入Schema与边界type Str = { type: 'string'; min: number; max: number; pattern?: RegExp } type Num = { type: 'number'; min: number; max: number; integer?: boolean } type Field = Str | Num type Schema = { properties: Record<string, Field>; required?: string[] } 二、生成器与变异function randInt(min: number, max: number): number { return Math.floor(Math.random() * (max - min + 1)) + min } function genStr(spec: Str): string { const len = randInt(spec.min, spec.max) const chars = 'abcdefghijklmnopqrstuvwxyz0123456789_-' + "<>\"'&" let s = '' for (let i = 0; i < len; i++) s += chars[randInt(0, chars.length - 1)] if (spec.pattern && !spec.pattern.test(s)) s = s.replace(/[<>"'&]/g, 'a') return s } function genNum(spec: Num): number { const n = spec.integer ? randInt(spec.min, spec.max) : Math.random() * (spec.max - spec.min) + spec.min return Math.min(spec.max, Math.max(spec.min, n)) } function mutateString(s: string): string { const ops = [ (x: string) => x + "' OR '1'='1", (x: string) => `<script>alert(1)</script>` + x, (x: string) => x.slice(0, 1), (x: string) => x.repeat(10) ] return ops[randInt(0, ops.length - 1)](s) } 三、速率限制与重放class RateGate { windowMs: number max: number hits = new Map<string, number[]>() constructor(windowMs: number, max: number) { this.windowMs = windowMs; this.max = max } allow(key: string): boolean { const now = Date.now() const arr = (this.hits.get(key) || []).filter(t => now - t < this.windowMs) if (arr.length >= this.max) return false arr.push(now); this.hits.set(key, arr); return true } } type Case = { input: Record<string, any>; id: string } class Corpus { items: Case[] = []; add(c: Case) { this.items.push(c) } get(i: number) { return this.items[i] } size() { return this.items.length } } 四、执行器与审计type Req = { path: string; method: string } type Res = { status: (n: number) => Res; end: (b?: string) => void } type Target = (input: Record<string, any>, req: Req, res: Res) => void type Audit = { id: string; caseId: string; route: string; method: string; ok: boolean; timestamp: string } function nowIso(): string { return new Date().toISOString() } function run(target: Target, schema: Schema, corpus: Corpus, gate: RateGate, req: Req, res: Res): Audit[] { const audits: Audit[] = [] for (let i = 0; i < corpus.size(); i++) { if (!gate.allow(req.path)) break const c = corpus.get(i) try { target(c.input, req, res); audits.push({ id: String(Date.now()) + i, caseId: c.id, route: req.path, method: req.method, ok: true, timestamp: nowIso() }) } catch { audits.push({ id: String(Date.now()) + i, caseId: c.id, route: req.path, method: req.method, ok: false, timestamp: nowIso() }) } } return audits } 五、样例与验收const schema: Schema = { properties: { username: { type: 'string', min: 3, max: 16, pattern: /^[a-z0-9_\-]+$/i }, age: { type: 'number', min: 0, max: 120, integer: true } }, required: ['username'] } const corpus = new Corpus() for (let i = 0; i < 50; i++) { const u = genStr(schema.properties['username'] as Str) const a = genNum(schema.properties['age'] as Num) corpus.add({ id: 'case_' + i, input: { username: i % 5 === 0 ? mutateString(u) : u, age: a } }) } 生成策略包含边界值与注入变异;RateGate生效;重放通过`caseId`与输入快照实现。审计包含`route/method/caseId/ok/timestamp`;覆盖统计可基于字段变异率与错误比例。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
1.699506s