`$graphLookup`'s full parser (`createFromBson`) uses a hand-written loop that unconditionally overwrites local variables on each matching field name. With duplicate BSON keys - eg `{ from: "A", ..., from: "B" }` - the last value wins at execution time. The lite parser reads the first matching element via `BSONObj::operator[]`, so auth sees a different namespace than the one execution actually queries. This is the root cause of CVE-381.
The fix adds a `StringDataSet seenFields` before the loop and asserts that each field name appears at most once, matching the behavior of IDL-generated parsers with `strict: true`. Two alternatives were considered:
1) Migrate `createFromBson` to call `DocumentSourceGraphLookUpSpec::parse()` on master and add `seenFields` only on older branches. The IDL spec exists on master but hasn't been backported, so this would mean two different fix strategies across versions.
2) Apply `seenFields` uniformly to all versions. This is what we're doing here.
I think option 2 is preferable - it keeps the backport mechanical and identical across all branches, and the `seenFields` check is straightforward to review in isolation without needing to understand the IDL refactor. The IDL exists for the extensions hybrid search project SPM-4532 and should be guarded behind a feature flag.