-
Type:
Bug
-
Resolution: Done
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
-
Server Security
-
Fully Compatible
-
ALL
-
Server Security 2026-07-03, Server Security 2026-07-17, Server Security 2026-07-31, Server Security 2026-08-14
-
None
-
None
-
None
-
None
-
None
-
None
-
None
The src/mongo/db/auth/README.md documentation is inconsistent with the actual authorization behavior regarding which collections are matched by the "Any normal collection" resource pattern (kMatchAnyNormalResource), which is the pattern granted by readAnyDatabase/readWriteAnyDatabase.
The "Normal resources" section states:
> Collection names starting with system. on any database, or starting with replset. on the local database are considered "special" and are not covered by the "Any normal collection" resource case. All other collections are considered normal collections.
And the kMatchAnyNormalResource table row states it "Matches all normal storage resources." Taken together, the docs imply that normal-by-name collections in the config and local databases (e.g. config.changelog, local.me) are covered by the "Any normal collection" resource.
This is incorrect. The doc conflates two distinct predicates:
- NamespaceString::isNormalCollection() — a collection-name-based property. The README's definition is accurate for this.
- Whether the namespace is matched by forAnyNormalResource. The resource pattern search list applies an additional carve-out excluding the entire config and local databases, regardless of whether the collection is normal by name:
if (nss.isNormalCollection()) {
// But even normal collections in non-normal databases should not be matchable with
// ResourcePattern::forAnyNormalResource. 'local' and 'config' are
// used to store special system collections, which user level
// administrators should not be able to manipulate.
if (!nss.isLocalDB() && !nss.isConfigDB()) {
_list[_size++] = ResourcePattern::forAnyNormalResource(target.tenantId());
}
_list[_size++] = ResourcePattern::forDatabaseName(nss.dbName());
}
Because readAnyDatabase uses matchType: any_normal, the set of collections it can access is strictly smaller than the set the README defines as normal: config and local are entirely excluded.
Proposed fix: Update the "Normal resources" section and the kMatchAnyNormalResource table row to document that, in addition to the collection-name rules, the config and local databases are entirely excluded from the "Any normal collection" resource match.