mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-15 11:22:15 +03:00
* fix(security): sanitize test regex and annotate CodeQL hash false-positives tests/unit/early-sse-route-intent.test.ts built a RegExp from a hardcoded string but only escaped `?`/`.`, missing `\` — js/incomplete-sanitization (#816). Not exploitable (fixed literal input) but the escaping was genuinely incomplete; now escapes backslash too. reasoningCache.ts::buildAssistantMessageCacheKey and codexIdentity.ts's two UUID derivation helpers hash a cache-scope/account-seed with SHA-256 to produce a lookup key / deterministic ID — not a stored, verified password. CodeQL's js/insufficient-password-hash overfires on any hash of a secret-like variable, the same false-positive class already annotated at src/lib/db/apiKeys.ts:624. Added matching lgtm/nosemgrep annotations and inline rationale so the intent is clear to reviewers and future scans. Refs #815 #816 #817 #818 * fix(security): keep only the regex sanitization; drop non-functional CodeQL annotations The lgtm[]/nosemgrep: comments in codexIdentity.ts and reasoningCache.ts use formats GitHub Actions CodeQL does not honor, and shifting those sha256 lines re-attributed the already-dismissed base alerts to this PR as two new CodeQL findings. Revert those two annotation-only files to base so the existing dismissals apply; retain the real fix (escaping backslash in the test regex), which resolves the open js/incomplete-sanitization alert. --------- Co-authored-by: Xiangzhe <bakryun0718@proton.me> Co-authored-by: adevwithpurpose <adevwithpurpose@users.noreply.github.com>
43 lines
1.6 KiB
TypeScript
43 lines
1.6 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
import { resolveStreamFlag } from "../../open-sse/utils/aiSdkCompat.ts";
|
|
|
|
const ROUTES = [
|
|
{
|
|
name: "responses",
|
|
sourceFormat: "openai-responses",
|
|
bodyExpression: "resolvedBody?.stream",
|
|
source: fs.readFileSync(path.join("src", "app", "api", "v1", "responses", "route.ts"), "utf8"),
|
|
},
|
|
{
|
|
name: "messages",
|
|
sourceFormat: "claude",
|
|
bodyExpression: "body?.stream",
|
|
source: fs.readFileSync(path.join("src", "app", "api", "v1", "messages", "route.ts"), "utf8"),
|
|
},
|
|
] as const;
|
|
|
|
for (const route of ROUTES) {
|
|
test(`${route.name} early-heartbeat gate uses the real stream resolver`, () => {
|
|
const escapedBodyExpression = route.bodyExpression.replace(/[.?\\]/g, "\\$&");
|
|
assert.match(
|
|
route.source,
|
|
new RegExp(
|
|
`resolveStreamFlag\\(\\s*${escapedBodyExpression},\\s*accept,\\s*"${route.sourceFormat}"\\s*\\)`
|
|
)
|
|
);
|
|
assert.match(route.source, /if \(wantsStreaming\) \{[\s\S]*withEarlyStreamKeepalive\(/);
|
|
assert.doesNotMatch(route.source, /accept\.includes\(["']text\/event-stream["']\)/);
|
|
});
|
|
|
|
test(`${route.name} stream intent covers body and Accept without overriding stream:false`, () => {
|
|
assert.equal(resolveStreamFlag(true, "application/json", route.sourceFormat), true);
|
|
assert.equal(resolveStreamFlag(false, "text/event-stream", route.sourceFormat), false);
|
|
assert.equal(resolveStreamFlag(undefined, "text/event-stream", route.sourceFormat), true);
|
|
assert.equal(resolveStreamFlag(undefined, "application/json", route.sourceFormat), false);
|
|
});
|
|
}
|