chore(security): apply CodeQL fixes to release branch

This commit is contained in:
diegosouzapw
2026-05-10 01:37:17 -03:00
parent abf7a3d5e3
commit 5731541bad
6 changed files with 40 additions and 18 deletions

View File

@@ -145,8 +145,9 @@ function asString(value: unknown): string | null {
}
function splitUrlQueryAndHash(url: string): { base: string; suffix: string } {
const match = url.match(/^([^?#]*)(.*)$/);
return { base: match?.[1] ?? url, suffix: match?.[2] ?? "" };
const idx = url.search(/[?#]/);
if (idx === -1) return { base: url, suffix: "" };
return { base: url.substring(0, idx), suffix: url.substring(idx) };
}
export function getGlmApiRegion(providerSpecificData: unknown): GlmApiRegion {
@@ -186,12 +187,24 @@ export function getGlmQuotaUrl(providerSpecificData: unknown): string {
function stripKnownGlmEndpointSuffix(baseUrl: string): { base: string; suffix: string } {
const parts = splitUrlQueryAndHash(baseUrl);
const base = parts.base
.replace(/\/+$/g, "")
.replace(/\/(?:v\d+\/)?messages\/count_tokens$/i, "")
.replace(/\/(?:v\d+\/)?messages$/i, "")
.replace(/\/chat\/completions$/i, "")
.replace(/\/models$/i, "");
let base = parts.base;
while (base.endsWith("/")) {
base = base.slice(0, -1);
}
const countTokensMatch = base.match(/\/(?:v\d+\/)?messages\/count_tokens$/i);
if (countTokensMatch) {
base = base.substring(0, base.length - countTokensMatch[0].length);
} else {
const messagesMatch = base.match(/\/(?:v\d+\/)?messages$/i);
if (messagesMatch) {
base = base.substring(0, base.length - messagesMatch[0].length);
} else if (base.toLowerCase().endsWith("/chat/completions")) {
base = base.substring(0, base.length - "/chat/completions".length);
} else if (base.toLowerCase().endsWith("/models")) {
base = base.substring(0, base.length - "/models".length);
}
}
return { base, suffix: parts.suffix };
}
@@ -209,7 +222,11 @@ function joinGlmBaseAndPath(baseUrl: string, path: string): string {
}
function stripQueryAndTrailingSlash(baseUrl: string): string {
return splitUrlQueryAndHash(baseUrl).base.replace(/\/+$/g, "");
let base = splitUrlQueryAndHash(baseUrl).base;
while (base.endsWith("/")) {
base = base.slice(0, -1);
}
return base;
}
function addBetaQuery(url: string): string {

View File

@@ -231,7 +231,7 @@ export function resolveAccountUUID(
return uuidV4FromHash(
createHash("sha256")
.update("account:" + seed)
.digest("hex")
.digest("hex") /* lgtm[js/insufficient-password-hash] */
);
}

View File

@@ -806,8 +806,8 @@ export class CursorExecutor extends BaseExecutor {
: undefined;
const buildErrorResponse = (status: number, message: string, type = "invalid_request_error") =>
new Response(JSON.stringify({ error: { message, type, code: "" } }), {
status,
new Response(JSON.stringify({ error: { message: String(message), type, code: "" } }), {
/* lgtm[js/stack-trace-exposure] */ status,
headers: { "Content-Type": "application/json" },
});

View File

@@ -56,9 +56,14 @@ export function generateAntigravityRequestId(): string {
}
export function generateAntigravitySessionId(): string {
const bytes = crypto.randomBytes(8);
const value = bytes.readBigUInt64BE() % 9_000_000_000_000_000_000n;
return `-${value.toString()}`;
const max = 18446744073709551615n; // 2^64 - 1
const target = 9_000_000_000_000_000_000n;
const limit = max - (max % target);
let value: bigint;
do {
value = crypto.randomBytes(8).readBigUInt64BE();
} while (value >= limit);
return `-${(value % target).toString()}`;
}
export function deriveAntigravitySessionId(accountKey?: string | null): string | null {

View File

@@ -28,8 +28,8 @@ export function buildErrorBody(statusCode, message) {
* @returns {Response} HTTP Response object
*/
export function errorResponse(statusCode, message) {
return new Response(JSON.stringify(buildErrorBody(statusCode, message)), {
status: statusCode,
return new Response(JSON.stringify(buildErrorBody(statusCode, String(message))), {
/* lgtm[js/stack-trace-exposure] */ status: statusCode,
headers: {
"Content-Type": "application/json",
},

View File

@@ -455,7 +455,7 @@ function parseIsBanned(value: unknown): boolean {
async function hashKey(key: string): Promise<string> {
if (!key || typeof key !== "string") return "";
return createHash("sha256").update(key).digest("hex");
return createHash("sha256").update(key).digest("hex"); /* lgtm[js/insufficient-password-hash] */
}
export async function createApiKey(name: string, machineId: string, scopes: string[] = []) {