mirror of
https://github.com/affaan-m/ECC.git
synced 2026-10-26 18:35:05 +00:00
fix(session-aliases): reject array-shaped alias maps
This commit is contained in:
1 parent
76aaa77df6
commit
b1668579f6
2 files changed
+8
-19
No files matched your search
@@ -58,7 +58,7 @@ function loadAliases() {
|
||||
const data = JSON.parse(content);
|
||||
|
||||
// Validate structure
|
||||
if (!data.aliases || typeof data.aliases !== 'object') {
|
||||
if (!data.aliases || typeof data.aliases !== 'object' || Array.isArray(data.aliases)) {
|
||||
log('[Aliases] Invalid aliases file structure, resetting');
|
||||
return getDefaultAliases();
|
||||
}
|
||||
|
||||
@@ -1304,15 +1304,8 @@ function runTests() {
|
||||
'Persisted title should be null after round-trip through saveAliases/loadAliases');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// ── Round 103: loadAliases with array aliases in JSON (typeof [] === 'object' bypass) ──
|
||||
console.log('\nRound 103: loadAliases (array aliases — typeof bypass):');
|
||||
if (test('loadAliases accepts array aliases because typeof [] === "object" passes validation', () => {
|
||||
// session-aliases.js line 58: `typeof data.aliases !== 'object'` is the guard.
|
||||
// Arrays are typeof 'object' in JavaScript, so {"aliases": [1,2,3]} passes
|
||||
// validation. The returned data.aliases is an array, not a plain object.
|
||||
// Downstream code (Object.keys, Object.entries, bracket access) behaves
|
||||
// differently on arrays vs objects but doesn't crash — it just produces
|
||||
// unexpected results like numeric string keys "0", "1", "2".
|
||||
console.log('\nArray alias maps:');
|
||||
if (test('recovers an invalid array map without losing newly saved aliases', () => {
|
||||
resetAliases();
|
||||
const aliasesPath = aliases.getAliasesPath();
|
||||
fs.writeFileSync(aliasesPath, JSON.stringify({
|
||||
@@ -1321,15 +1314,11 @@ function runTests() {
|
||||
metadata: { totalCount: 3, lastUpdated: new Date().toISOString() }
|
||||
}));
|
||||
const data = aliases.loadAliases();
|
||||
// The array passes the typeof 'object' check and is returned as-is
|
||||
assert.ok(Array.isArray(data.aliases),
|
||||
'data.aliases should be an array (typeof [] === "object" bypasses guard)');
|
||||
assert.strictEqual(data.aliases.length, 3,
|
||||
'Array should have 3 elements');
|
||||
// Object.keys on an array returns ["0", "1", "2"] — numeric index strings
|
||||
const keys = Object.keys(data.aliases);
|
||||
assert.deepStrictEqual(keys, ['0', '1', '2'],
|
||||
'Object.keys of array returns numeric string indices, not named alias keys');
|
||||
assert.deepStrictEqual(data.aliases, {});
|
||||
assert.deepStrictEqual(aliases.listAliases(), []);
|
||||
assert.strictEqual(aliases.setAlias('recovered', '/session/recovered').success, true);
|
||||
assert.strictEqual(aliases.resolveAlias('recovered').sessionPath, '/session/recovered');
|
||||
assert.strictEqual(aliases.loadAliases().metadata.totalCount, 1);
|
||||
})) passed++; else failed++;
|
||||
|
||||
// ── Round 104: resolveSessionAlias with path-traversal input (passthrough without validation) ──
|
||||
|
||||
Reference in new issue
Block a user