Principle violated: "Worse is Better" — but "better" presumes correctness first. Order-dependent iteration over unordered data is not correct by any definition.
The Bug
The permission evaluation system iterates over permission records using Object.entries() or equivalent enumeration of a plain object, and the evaluation result depends on the order in which keys are processed.
JavaScript does not guarantee property order for integer-like keys in certain edge cases, and Object.entries() behavior with symbol-keyed or mixed-type properties can produce surprising orderings. When permission evaluation depends on which rule matches first, an order change silently changes the security decision.
Why This Is Wrong
- Security decisions should be deterministic regardless of property enumeration order. If two permission rules have overlapping patterns (e.g.,
"config.*" and "config.sensitive.*"), and the evaluation result depends on which one the runtime iterates first, the permission system is incorrect.
- V8 ordering guarantees are not the ECMAScript specification. Engine-specific behavior is not a contract. If Node.js changes property ordering in a future version, or if this code runs in a different JS engine (Bun, Deno), the behavior changes silently.
- No explicit priority or ordering mechanism. The system should define evaluation order by an explicit property (priority number, pattern length sorted, etc.) rather than relying on insertion order.
Fix
- Define an explicit ordering mechanism for permission rules (e.g., a
priority field, or sort by pattern specificity in a deterministic way).
- Add tests that prove overlapping patterns produce the correct result regardless of declaration order.
- Consider using
Map instead of {} for permission collections if insertion order is the intended behavior — at least Map guarantees iteration order per the spec.
Principle violated: "Worse is Better" — but "better" presumes correctness first. Order-dependent iteration over unordered data is not correct by any definition.
The Bug
The permission evaluation system iterates over permission records using
Object.entries()or equivalent enumeration of a plain object, and the evaluation result depends on the order in which keys are processed.JavaScript does not guarantee property order for integer-like keys in certain edge cases, and
Object.entries()behavior with symbol-keyed or mixed-type properties can produce surprising orderings. When permission evaluation depends on which rule matches first, an order change silently changes the security decision.Why This Is Wrong
"config.*"and"config.sensitive.*"), and the evaluation result depends on which one the runtime iterates first, the permission system is incorrect.Fix
priorityfield, or sort by pattern specificity in a deterministic way).Mapinstead of{}for permission collections if insertion order is the intended behavior — at leastMapguarantees iteration order per the spec.