java-topology/whitepaper/outreach/forgejo-0003.md
russell@unturf.com 652608142a feat: close outreach doc gap — 276 docs (batches 11-16)
All projects with patches now have outreach docs. 276 new docs covering
CWE-407, CWE-312, CWE-362 across C, C++, Java, Python, Go, Rust, C#,
PHP, Ruby, JavaScript, Dart, Erlang, R, and more.

Outreach gap: 276 -> 0.
2026-04-15 13:57:42 -04:00

2.2 KiB

Forgejo — CWE-407 Disclosure Brief (forgejo-0003)

2026-04-13 · Patch available — awaiting upstream merge

Finding

One O(K*G) defect in Forgejo's SSH public key synchronization for LDAP/OAuth sources. Patched. Patch ready for upstream review.

The Defects

forgejo-0003 (PATCHED — MEDIUM): models/asymkey/ssh_key.go:378

// In synchronizePublicKeys() — fires during LDAP/OAuth user sync:
if !util.SliceContainsString(providedKeys, key) {  // O(K) dedup
    providedKeys = append(providedKeys, key)
}
// ...
if !util.SliceContainsString(giteaKeys, key) {     // O(G) scan
    newKeys = append(newKeys, key)
}
// ...
if !util.SliceContainsString(providedKeys, giteaKey) { // O(K) scan
    giteaKeysToDelete = append(giteaKeysToDelete, giteaKey)
}

Three separate O(N) linear scans: dedup of provided keys O(K^2), diff new keys O(KG), diff deleted keys O(GK). With K provided keys and G existing Gitea keys, total cost reaches O(K^2 + KG + GK).

Complexity Proof

At K=200 provided keys, G=200 Gitea keys:

  • Defective: 200^2 + 200x200 + 200x200 = 120,000 comparisons
  • Fixed: 200 + 200 + 200 = 600 lookups (map)
  • 200x op reduction.

Impact

Forgejo synchronizes SSH keys from LDAP/OAuth identity providers. Organizations with many SSH keys per user (deploy keys, personal keys, service accounts) trigger this path during every authentication sync cycle.

The Fix

Build map[string]struct{} sets for both provided and Gitea key lists:

// Before
util.SliceContainsString(providedKeys, key)

// After
providedKeysSet[key]

Patch

Fix available: defects/forgejo-0003/patch/forgejo-0003.patch

Single-file patch on models/asymkey/ssh_key.go. 200x speedup at K=200, G=200 keys.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a Forgejo issue reference (codeberg.org/forgejo/forgejo).
  2. Assess severity — fires during SSH key sync; scales with key count.
  3. Coordinate a disclosure date — we are targeting 90 days from first contact.
  4. We will credit the Forgejo team in the public disclosure. Preferred acknowledgment format welcome.

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