| عنوان | Milvus v2.6.13 Authorization Bypass` / `Hash Collision` / `Privilege Escalation |
|---|
| الوصف | ## Summary
Milvus uses a truncated MD5-derived value as the RBAC `grantee-id` binding identifier for authorization metadata. The implementation keeps only 64 bits of the MD5 output and uses that short value to map `role/object/db/objectName` relationships to the privilege subtree under `root-coord/credential/grantee-id/<id>/...`.
Because the identifier is only 64 bits wide, different authorization relationships can be forced to share the same `grantee-id` namespace. Once such aliasing occurs, a victim role can resolve the donor role's privileges, leading to cross-role privilege forgery and authorization bypass.
## Technical Root Cause
Affected code paths:
- [pkg/util/crypto/crypto.go](/mnt/nas/gitRepo/repos/408/pkg/util/crypto/crypto.go:44)
- [internal/metastore/kv/rootcoord/kv_catalog.go](/mnt/nas/gitRepo/repos/408/internal/metastore/kv/rootcoord/kv_catalog.go:1293)
- [internal/metastore/kv/rootcoord/kv_catalog.go](/mnt/nas/gitRepo/repos/408/internal/metastore/kv/rootcoord/kv_catalog.go:1301)
Relevant logic:
```go
func MD5(str string) string {
data := md5.Sum([]byte(str))
return hex.EncodeToString(data[:])[8:24]
}
```
```go
idStr = crypto.MD5(k)
err = kc.Txn.Save(ctx, k, idStr)
...
k = fmt.Sprintf("%s/%s/%s", GranteeIDPrefix, idStr, privilegeName)
```
This reduces the authorization binding identifier from a full 128-bit MD5 digest to a 64-bit truncated namespace.
## Affected Authorization Model
Milvus stores RBAC metadata in two linked layers:
```text
root-coord/credential/grantee-privileges/<role>/<object>/<db>.<objectName> -> grantee-id
root-coord/credential/grantee-id/<id>/<privilege> -> grantor
```
If two different `grantee-privileges/...` parent keys share the same `grantee-id`, the privilege subtree becomes shared. As a result, one role can resolve another role's privileges.
## Reproduction
### Environment
- Local Docker standalone deployment
- Authorization enabled
- Public privilege disabled
- Builtin admin role initialized
- `pymilvus 3.0.0`
### Reproduction Steps
1. Start a local Milvus standalone stack with RBAC enabled.
2. Create:
- donor role
- victim role
- victim user
- one test collection
3. Grant donor role:
- `Insert` on `Collection/default.<collection>`
- `DescribeCollection` on `Global/default.*`
- `ListAliases` on `Global/default.*`
4. Verify the victim user is denied before aliasing:
- `insert` fails with `PrivilegeDescribeCollection: permission deny`
5. Modify local etcd metadata so the victim parent grant keys point to the donor `grantee-id` values.
6. Restart `milvus-auth-standalone`.
7. Re-run the same `insert` request as the victim user.
8. Observe successful insert.
## Proof of Impact
Observed local auth-enabled etcd state:
```text
by-dev/meta/root-coord/credential/grantee-privileges/rbac_final_donor_role/Collection/default.rbac_final_demo_coll
991e0703faf96595
by-dev/meta/root-coord/credential/grantee-privileges/rbac_final_victim_role/Collection/default.rbac_final_demo_coll
991e0703faf96595
by-dev/meta/root-coord/credential/grantee-privileges/rbac_final_donor_role/Global/default.*
0bc041feeaa6cd7b
by-dev/meta/root-coord/credential/grantee-privileges/rbac_final_victim_role/Global/default.*
0bc041feeaa6cd7b
```
Observed behavior:
- Before aliasing:
```text
PrivilegeDescribeCollection: permission deny to rbac_final_victim_user in the `default` database
```
- After aliasing and restart:
```text
insert SUCCESS {'insert_count': 1, 'ids': [5]}
```
This demonstrates a real authorization bypass in the local Docker environment.
## Attack Requirements
The vulnerability becomes exploitable once an attacker can influence or rewrite RBAC grant metadata so that two different grant parent keys share the same 64-bit `grantee-id`.
Practical attacker models include:
- control-plane compromise with write access to etcd
- privileged internal operator or automation account that can manipulate RBAC metadata paths
- any path that allows attacker-controlled grant keys to be persisted and collided into the same authorization namespace
This is not a low-privilege anonymous remote issue by itself, but it is a real privilege-forgery primitive once control-plane or RBAC metadata influence exists.
## Security Impact
- Cross-role privilege forgery
- Authorization namespace collision
- Privilege escalation
- Object-level permission spoofing
- Integrity loss of RBAC policy evaluation
An attacker can cause a victim role to inherit donor privileges on arbitrary targeted objects once the relevant grant-key alias is achieved.
## Why This Matters
Full MD5 output is 128 bits, but Milvus truncates the digest to 64 bits before using it as an authorization binding identifier. This is the decisive weakness.
The issue is not merely that MD5 is old; it is that a security-sensitive identifier used to bind authorization state is reduced below a reasonable security margin. That makes arbitrary collisions dramatically more practical than they would be with a full-width identifier.
## Recommended Fix
Do not derive RBAC `grantee-id` from a truncated hash.
Recommended options:
1. Use a non-truncated collision-resistant identifier of at least 128 bits.
2. Prefer a canonical reversible encoding of the full logical grant key instead of a hash-derived short identifier.
3. Migrate existing metadata so old 64-bit `grantee-id` mappings cannot continue to alias unrelated grants.
4. Add regression tests that ensure different grant parent keys cannot resolve into the same privilege namespace.
## Supporting Files
- [bug.MD](/mnt/nas/gitRepo/repos/408/bug.MD:1)
- [rbac_grantee_id_probe.py](/mnt/nas/gitRepo/repos/408/scripts/rbac_grantee_id_probe.py:1)
- [rbac_grantee_md5_bruteforce_bench.py](/mnt/nas/gitRepo/repos/408/scripts/rbac_grantee_md5_bruteforce_bench.py:1)
- [rbac_grantee_alias_poc.py](/mnt/nas/gitRepo/repos/408/scripts/rbac_grantee_alias_poc.py:1)
- [docker-compose-auth.yml](/mnt/nas/gitRepo/repos/408/deployments/docker/standalone/docker-compose-auth.yml:1)
## References
- VulDB Submission Policy: https://vuldb.com/kb/submission
- OWASP Session Management Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
- OWASP Session Prediction: https://owasp.org/www-community/attacks/Session_Prediction
|
|---|
| المصدر | ⚠️ https://github.com/milvus-io/milvus/issues/49857 |
|---|
| المستخدم | Dem00 (UID 84913) |
|---|
| ارسال | 16/05/2026 06:57 PM (19 أيام منذ) |
|---|
| الاعتدال | 04/06/2026 07:42 AM (19 days later) |
|---|
| الحالة | تمت الموافقة |
|---|
| إدخال VulDB | 368262 [milvus-io milvus حتى 2.6.13 Grantee ID Hash kv_catalog.go تشفير ضعيف] |
|---|
| النقاط | 20 |
|---|