69 lines
2.6 KiB
TypeScript
69 lines
2.6 KiB
TypeScript
// tests/unit/main/ipc/paths-no-path-leak.test.ts
|
|
//
|
|
// 守 audit-r244「白名单拒绝消息不回显绝对路径」契约。
|
|
//
|
|
// 问题:ipc/wrap.ts 只对 **INTERNAL** 走 scrubInternal(把 rootPath **之内**
|
|
// 的路径替成占位符);已知 code(EPERM 等)是**原样透传**的。而
|
|
// `assertInsideAllowedRoot` 的 EPERM 消息里带着 `abs` —— 恰恰是
|
|
// rootPath **之外**的路径(scrubInternal 恰恰脱敏不到它)⇒ 家目录 /
|
|
// OneDrive 目录名随 IPC 错误回包进 renderer 与 telemetry。
|
|
//
|
|
// 口径已由 ipc/shell.ts(r229)、ipc/library.ts(r191)确立:消息不含路径,
|
|
// 完整路径只留 main 侧日志。paths.ts 是**源头**,之前靠三个调用点各自
|
|
// 改写文案才没漏 —— 属「运气」而非「设计」,新调用点一接就漏。
|
|
//
|
|
// 本测锁:白名单拒绝抛出的 AppError.message 里既没有越界路径,也没有
|
|
// 工作区根路径。
|
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
import { promises as fs } from 'fs';
|
|
import { join } from 'path';
|
|
import { tmpdir } from 'os';
|
|
|
|
import { setRootPath } from '../../../../src/main/utils/safe-write';
|
|
import { assertInsideAllowedRoot } from '../../../../src/main/ipc/paths';
|
|
import { AppError } from '../../../../src/main/utils/error';
|
|
|
|
describe('audit-r244:白名单拒绝消息不含绝对路径', () => {
|
|
let root: string;
|
|
let outside: string;
|
|
|
|
beforeEach(async () => {
|
|
root = await fs.mkdtemp(join(tmpdir(), 'rkms-pathleak-root-'));
|
|
outside = await fs.mkdtemp(join(tmpdir(), 'rkms-pathleak-out-'));
|
|
setRootPath(root);
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await fs.rm(root, { recursive: true, force: true });
|
|
await fs.rm(outside, { recursive: true, force: true });
|
|
});
|
|
|
|
it('工作区外的绝对路径 → EPERM,消息里既无越界路径也无根路径', () => {
|
|
const secret = join(outside, 'id_rsa');
|
|
let err: unknown;
|
|
try {
|
|
assertInsideAllowedRoot(secret);
|
|
} catch (e: unknown) {
|
|
err = e;
|
|
}
|
|
expect(err).toBeInstanceOf(AppError);
|
|
const appErr = err as AppError;
|
|
expect(appErr.code).toBe('EPERM');
|
|
expect(appErr.message).not.toContain(secret);
|
|
expect(appErr.message).not.toContain(outside);
|
|
expect(appErr.message).not.toContain(root);
|
|
});
|
|
|
|
it('工作区外的相对路径(基于 root 解析后越界)→ 同样不含路径', () => {
|
|
let err: unknown;
|
|
try {
|
|
assertInsideAllowedRoot('../escape-outside');
|
|
} catch (e: unknown) {
|
|
err = e;
|
|
}
|
|
expect(err).toBeInstanceOf(AppError);
|
|
expect((err as AppError).code).toBe('EPERM');
|
|
expect((err as AppError).message).not.toContain(root);
|
|
});
|
|
});
|