# Dgraph — CWE-407 Disclosure Brief
**2026-03-27 · Patch available — awaiting upstream merge**

## Finding

One O(n²) defect in Dgraph's k-shortest-paths BFS implementation. The path deduplication check uses `route.indexOf(toUid)` — a linear slice scan — inside the BFS neighbour expansion loop. Patch ready for upstream review.

## The Defects

**dgraph-0001 (PATCHED — HIGH):** `query/shortest.go:380`

```go
// route: []uint64 (path as uid slice)
// Inside k-shortest-paths BFS neighbour expansion:
if route.indexOf(toUid) >= 0 {  // O(P) linear slice scan per neighbour
    continue
}
```

`route.indexOf(toUid)` performs a linear scan over P path elements for every neighbour considered during BFS expansion. For a path of length P with N neighbours per node: **O(P) per neighbour check, O(N×P) per node expansion**.

## Complexity Proof

For k-shortest-paths BFS with P nodes per path and N neighbours per node:
- Per neighbour expansion: O(P) `indexOf` scan
- Total across all expansions: **O(N × P²)**

At P=501: defective scan has 501 comparisons per neighbour, fixed has 1 map lookup. **Measured ratio: 501×.**

## Impact

All Dgraph users running shortest-path queries (`shortest` function in DQL or equivalent). Affected workloads include knowledge graph traversal, recommendation engines, route optimization, and any application using k-shortest-paths. Dgraph is deployed in production graph databases for social networks and enterprise knowledge graphs.

## The Fix

Replace the slice scan with a `map[uint64]struct{}` alongside the path:

```go
// Before
if route.indexOf(toUid) >= 0 {
    continue
}

// After
// CWE-407 fix: map[uint64]struct{} for O(1) membership instead of O(P) slice scan.
routeSet := make(map[uint64]struct{})
for _, uid := range route {
    routeSet[uid] = struct{}{}
}
if _, exists := routeSet[toUid]; exists {
    continue
}
```

## Patch

`defects/dgraph/patch/dgraph-0001-shortest-map-visited.patch`

## What We Ask

1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
2. Validate the patch against your shortest-path query test suite.
3. Assess CVE eligibility — fires on every k-shortest-paths query on graphs with long paths.
4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.
