From 8fec49dae95dd3963aa77be1c858b6be2de54e0d Mon Sep 17 00:00:00 2001 From: Blake Byrnes Date: Tue, 19 Mar 2024 09:10:09 -0400 Subject: [PATCH] feat: strip sensitive info form logs fix(commons): fix serializing uint8array --- commons/lib/Logger.ts | 43 ++++++++++++++++++++--------------- commons/lib/TypeSerializer.ts | 14 +++++++----- commons/lib/dirUtils.ts | 19 +++------------- commons/lib/envUtils.ts | 5 ++-- 4 files changed, 38 insertions(+), 43 deletions(-) diff --git a/commons/lib/Logger.ts b/commons/lib/Logger.ts index fe9423a..3241df6 100644 --- a/commons/lib/Logger.ts +++ b/commons/lib/Logger.ts @@ -2,6 +2,21 @@ import { inspect } from 'util'; import ILog, { ILogData } from '../interfaces/ILog'; +declare global { + function UlixeeLogCreator(module: NodeModule): { + log: ILog; + }; + + // eslint-disable-next-line no-var,vars-on-top + var UlxLogPrototype: Log; + // eslint-disable-next-line no-var,vars-on-top + var UlxLogFilters: any; + // eslint-disable-next-line no-var,vars-on-top + var UlxLoggerSessionIdNames: Map; + // eslint-disable-next-line no-var,vars-on-top + var UlxSubscriptions: Map any>; +} + const hasBeenLoggedSymbol = Symbol.for('UlxHasBeenLogged'); global.UlxLogFilters ??= { @@ -122,8 +137,13 @@ class Log implements ILog { } } -function translateValueToPrintable(value: any, depth = 0): any { +function translateValueToPrintable(key: string, value: any, depth = 0): any { if (value === undefined || value === null) return; + + if (key === 'password' || key === 'suri') { + return '********'; + } + if (value instanceof Error) { return value.toString(); } @@ -150,11 +170,11 @@ function translateValueToPrintable(value: any, depth = 0): any { if (typeof value === 'object') { if (Array.isArray(value)) { - return value.map(x => translateValueToPrintable(x, depth + 1)); + return value.map((x, i) => translateValueToPrintable(i as any, x, depth + 1)); } const result: any = {}; - for (const [key, subValue] of Object.entries(value)) { - result[key] = translateValueToPrintable(subValue, depth + 1); + for (const [subKey, subValue] of Object.entries(value)) { + result[subKey] = translateValueToPrintable(subKey, subValue, depth + 1); } return result; } @@ -188,7 +208,7 @@ export function translateToPrintable( continue; } - const printable = translateValueToPrintable(value); + const printable = translateValueToPrintable(key, value); if (printable === null || printable === undefined) continue; printData[key] = printable; } @@ -197,17 +217,6 @@ export function translateToPrintable( const logLevels = { stats: 0, info: 1, warn: 2, error: 3 }; -declare global { - function UlixeeLogCreator(module: NodeModule): { - log: ILog; - }; - // eslint-disable-next-line no-var,vars-on-top - var UlixeeLogClass: typeof Log; - // eslint-disable-next-line no-var,vars-on-top - var UlxLoggerSessionIdNames: Map; - // eslint-disable-next-line no-var,vars-on-top - var UlxSubscriptions: Map any>; -} if (!global.UlixeeLogCreator) { global.UlixeeLogCreator = (module: NodeModule): { log: ILog } => { @@ -224,8 +233,6 @@ if (!global.UlixeeLogCreator) { }; } -global.UlixeeLogClass ??= Log; - export default function logger(module: NodeModule): ILogBuilder { return global.UlixeeLogCreator(module); } diff --git a/commons/lib/TypeSerializer.ts b/commons/lib/TypeSerializer.ts index 2e9363e..8a76b6d 100644 --- a/commons/lib/TypeSerializer.ts +++ b/commons/lib/TypeSerializer.ts @@ -173,8 +173,9 @@ export default class TypeSerializer { } if (ArrayBuffer.isView(value)) { - // @ts-ignore - const binary = new TextDecoder('utf8').decode(value.buffer); + const binary = Array.from(new Uint8Array(value.buffer, value.byteOffset, value.byteLength)) + .map(byte => String.fromCharCode(byte)) + .join(''); return { __type: Types.ArrayBuffer64, value: globalThis.btoa(binary), @@ -186,8 +187,7 @@ export default class TypeSerializer { }; } if (value instanceof ArrayBuffer) { - // @ts-ignore - const binary = new TextDecoder('utf8').decode(value); + const binary = Array.from(new Uint8Array(value)).map(byte => String.fromCharCode(byte)).join(''); return { __type: Types.ArrayBuffer64, value: globalThis.btoa(binary), @@ -219,8 +219,10 @@ export default class TypeSerializer { } const decoded = globalThis.atob(value); - // @ts-ignore - const uint8Array = new TextEncoder().encode(decoded); + const uint8Array = new Uint8Array(new ArrayBuffer(decoded.length)); + for (let i = 0; i < decoded.length; i++) { + uint8Array[i] = decoded.charCodeAt(i); + } if (!entry.args) return uint8Array; const { arrayType, byteOffset, byteLength } = entry.args; diff --git a/commons/lib/dirUtils.ts b/commons/lib/dirUtils.ts index affff78..c41f920 100644 --- a/commons/lib/dirUtils.ts +++ b/commons/lib/dirUtils.ts @@ -3,23 +3,10 @@ import * as Path from 'path'; import * as Fs from 'fs'; import { existsAsync } from './fileUtils'; -export function getCacheDirectory(): string { - if (process.platform === 'linux') { - return process.env.XDG_CACHE_HOME || Path.join(os.homedir(), '.cache'); - } - - if (process.platform === 'darwin') { - return Path.join(os.homedir(), 'Library', 'Caches'); - } - - if (process.platform === 'win32') { - return process.env.LOCALAPPDATA || Path.join(os.homedir(), 'AppData', 'Local'); - } - - throw new Error(`Unsupported platform: ${process.platform}`); -} - export function getDataDirectory(): string { + if (process.env.ULX_DATA_DIR) { + return process.env.ULX_DATA_DIR; + } if (process.platform === 'linux') { return process.env.XDG_DATA_HOME || Path.join(os.homedir(), '.local', 'share'); } diff --git a/commons/lib/envUtils.ts b/commons/lib/envUtils.ts index 5e3adef..94155a9 100644 --- a/commons/lib/envUtils.ts +++ b/commons/lib/envUtils.ts @@ -1,7 +1,7 @@ import * as Fs from 'fs'; -import * as Path from 'path'; import * as Os from 'os'; -import { getCacheDirectory, getDataDirectory } from './dirUtils'; +import * as Path from 'path'; +import { getDataDirectory } from './dirUtils'; /** * Will load env files with this precedence (.env.defaults, .env., .env) @@ -70,7 +70,6 @@ export function parseEnvInt(envvar: string): number | null { export function parseEnvPath(envvar: string, relativeTo?: string): string { if (!envvar) return undefined; if (envvar?.startsWith('~')) envvar = Path.join(Os.homedir(), envvar.slice(1)); - if (envvar?.startsWith('')) envvar = envvar.replace('', getCacheDirectory()); if (envvar?.startsWith('')) envvar = envvar.replace('', getDataDirectory()); if (envvar?.startsWith('')) envvar = envvar.replace('', Os.tmpdir()); if (Path.isAbsolute(envvar)) return envvar;