mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-15 19:57:07 +08:00
48 lines
1.6 KiB
JavaScript
48 lines
1.6 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const test = require('node:test');
|
|
const fs = require('node:fs');
|
|
const os = require('node:os');
|
|
const path = require('node:path');
|
|
const load = require('../helpers/load-security-module.cjs');
|
|
const { resolveFileAccess } = load(
|
|
path.join(__dirname, '../../back/shared/fileAccess.ts'),
|
|
);
|
|
|
|
test('file access enforces directory boundaries, blacklist descendants and symlinks', (t) => {
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'ql-file-security-'));
|
|
t.after(() => fs.rmSync(tmp, { recursive: true, force: true }));
|
|
const root = path.join(tmp, 'config');
|
|
fs.mkdirSync(path.join(root, 'grpc'), { recursive: true });
|
|
fs.mkdirSync(path.join(tmp, 'config-other'));
|
|
fs.writeFileSync(path.join(root, 'normal.txt'), 'normal');
|
|
fs.writeFileSync(path.join(root, 'grpc', 'client.key'), 'test-only');
|
|
fs.symlinkSync(path.join(tmp, 'config-other'), path.join(root, 'outside'));
|
|
fs.symlinkSync(path.join(root, 'grpc'), path.join(root, 'alias'));
|
|
fs.symlinkSync(path.join(root, 'normal.txt'), path.join(root, 'safe-link'));
|
|
fs.symlinkSync(path.join(tmp, 'missing'), path.join(root, 'dangling'));
|
|
for (const input of [
|
|
'../config-other/secret',
|
|
'/etc/passwd',
|
|
'grpc/client.key',
|
|
'alias/client.key',
|
|
'outside/new.txt',
|
|
'dangling',
|
|
'auth.json',
|
|
'nested/auth.json',
|
|
'',
|
|
]) {
|
|
assert.equal(
|
|
resolveFileAccess(root, [input], ['grpc', 'auth.json']),
|
|
'',
|
|
input,
|
|
);
|
|
}
|
|
for (const input of ['normal.txt', 'safe-link', 'new-dir/new.txt']) {
|
|
assert.equal(
|
|
resolveFileAccess(root, [input], ['grpc']),
|
|
path.join(root, input),
|
|
input,
|
|
);
|
|
}
|
|
});
|