This CVE stems from a null check that was written to prevent AttributeError but inadvertently created an authorization bypass when the referenced object was deleted. The original code likely read something like 'if conversion and not user.can_access(conversion): deny()' — the if conversion guard protected against accessing properties on a soft-deleted object, while the authorization check enforced access control. When conversion became None, the short-circuit evaluation skipped the authorization predicate entirely and the code fell through to permit access. The developer never consciously decided that deleted conversions should be public; the vulnerability emerged from the intersection of two independently reasonable code decisions that together created an unintended state.

This is the ergonomics failure that matters: the cognitive distance between writing a null guard and recognizing that 'object missing' is an authorization-relevant state. In feature development, the null check satisfies tests; the authorization logic satisfies requirements. Nobody's sprint backlog includes 'model the security implications of soft-deleted cross-references.' That threat model lives in no one's task description.

The fix is trivial — adding 'or conversion is None: deny()' — but that simplicity is itself revealing. If the fix required no sophisticated engineering, the gap was in review, not detection. This pattern almost certainly exists elsewhere in the codebase: authorization checks guarded by null-safety checks rather than explicit 'deleted' states. Other lifecycle states — expired, revoked, superseded, draft — likely exhibit the same vulnerability if they're modeled as null guards rather than first-class authorization conditions.

Audit your authorization logic for patterns like 'if obj and can_access(obj)' without explicit handling of non-existent references. Add test cases that exercise deleted-reference access to your authorization test suite. Consider whether your framework requires explicit modeling of lifecycle states or treats null-safety as a proxy for access control — the latter is a structural vulnerability waiting for the next deletion to trigger it.