Make log payloads opaque pass-through
This commit is contained in:
@@ -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}`)]));
|
||||
|
||||
Reference in New Issue
Block a user