Make log payloads opaque pass-through

This commit is contained in:
npc0-hue
2026-09-03 12:40:17 +08:00
parent 5b82a42cc4
commit bf3c382d15
16 changed files with 63 additions and 128 deletions
+4 -37
View File
@@ -16,7 +16,7 @@ import type {
const commandStates = new Set<GameClientBridgeCommandState>(["pending", "claimed", "succeeded", "failed", "cancelled", "expired", "unknown"]);
const resultStatuses = new Set<GameClientBridgeResultStatus>(["succeeded", "failed", "cancelled", "unknown"]);
const forbiddenKeys = new Set([
const forbiddenEnvelopeKeys = new Set([
"apikey",
"accesskey",
"accesskeyid",
@@ -47,19 +47,6 @@ const forbiddenKeys = new Set([
"storagecredential",
"token"
]);
const forbiddenFragments = [
"bearer ",
"password=",
"secret://",
"unix://",
"tcp://",
"mysql://",
"postgres://",
"sqlite://",
"rcon://"
];
const forbiddenHostPath = /(?:^|[\s"'])(?:\/[Uu]sers\/|\/home\/|\/root\/|\/var\/|\/etc\/|\/opt\/|[a-z]:[\\/]|\\\\[^\\]+\\)/;
export function parseSafeGameClientBridgeStatus(value: unknown): GameClientBridgeStatusResponse {
const record = safeObject(value, "Game Client Bridge status");
return {
@@ -191,32 +178,12 @@ function parseSnapshot(value: unknown): GameClientBridgeSnapshotResponse {
function safeObject(value: unknown, label: string): Record<string, unknown> {
const record = object(value, label);
rejectSensitiveProjection(record);
for (const key of Object.keys(record)) {
if (forbiddenEnvelopeKeys.has(key.toLowerCase().replace(/[^a-z0-9]/g, ""))) throw new Error("Game Client Bridge response contains a forbidden field");
}
return record;
}
function rejectSensitiveProjection(value: unknown): void {
if (typeof value === "string") {
const normalized = value.toLowerCase();
if (forbiddenFragments.some((fragment) => normalized.includes(fragment)) || forbiddenHostPath.test(value)) {
throw new Error("Game Client Bridge response contains sensitive connection or host data");
}
return;
}
if (Array.isArray(value)) {
value.forEach(rejectSensitiveProjection);
return;
}
if (value && typeof value === "object") {
for (const [key, child] of Object.entries(value)) {
if (forbiddenKeys.has(key.toLowerCase().replace(/[^a-z0-9]/g, ""))) {
throw new Error("Game Client Bridge response contains a forbidden field");
}
rejectSensitiveProjection(child);
}
}
}
function jsonObject(value: unknown, label: string): GameClientBridgeJsonObject {
const record = object(value, label);
return Object.fromEntries(Object.entries(record).map(([key, child]) => [key, jsonValue(child, `${label}.${key}`)]));