CVE-2021-22538 (published 2021-03-31T21:15Z)

A privilege escalation vulnerability impacting the Google Exposure Notification Verification Server (versions prior to 0.23.1), allows an attacker who (1) has UserWrite permissions and (2) is using a carefully crafted request or malicious proxy, to create another user with higher privileges than their own. This occurs due to insufficient checks on the allowed set of permissions. The new user creation event would be captured in the Event Log.

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-276
cwe_name: Incorrect Default Permissions
description: During installation, installed file permissions are set to allow anyone to modify those files.
extended_description: 
      
      
     
     

Fix information:
repo_url: https://github.com/google/exposure-notifications-verification-server
commit_details: repo_url: https://github.com/google/exposure-notifications-verification-server
author: Seth Vargo
author_date: 2021-03-15 11:11:56-04:00
msg: Merge pull request from GHSA-5v95-v8c8-3rh6

This fixes a security vulnerability where, with a carefully crafted request or malicious proxy, a user with UserWrite permissions could create another user with higher privileges than their own due to insufficient checks on the allowed set of permissions.
repository: repo_url: https://github.com/google/exposure-notifications-verification-server
repo_name: google/exposure-notifications-verification-server
description: Verification component for COVID-19 Exposure Notifications.
repo_language: Go
owner: google
file_changes: filename: rbac.go
change_type: ModificationType.MODIFY
diff: @@ -64,6 +64,16 @@ func Can(given Permission, target Permission) bool {
 func CompileAndAuthorize(actorPermission Permission, toUpdate []Permission) (Permission, error) {
 	var permission Permission
 	for _, update := range toUpdate {
+		// Verify the provided permission is a known permission. This prevents a
+		// security vulnerability whereby a carefully crafted request is able to
+		// provide a value that correctly passes an the bitwise AND check and then
+		// modifies the target permission using OR to escalate privilege.
+		if _, ok := PermissionMap[update]; !ok {
+			if update != LegacyRealmAdmin && update != LegacyRealmUser {
+				return 0, fmt.Errorf("provided permission %v is unknown", update)
+			}
+		}
+
 		// Verify that the user making changes has the permissions they are trying
 		// to grant. It is not valid for someone to grant permissions larger than
 		// they currently have.

programming_language: Go
filename: rbac_test.go
change_type: ModificationType.MODIFY
diff: @@ -57,6 +57,30 @@ func TestRequiredPermissions(t *testing.T) {
 			t.Errorf("expected error")
 		}
 	})
+
+	t.Run("legacy_admin", func(t *testing.T) {
+		t.Parallel()
+
+		if _, err := CompileAndAuthorize(LegacyRealmAdmin, []Permission{LegacyRealmAdmin}); err != nil {
+			t.Error(err)
+		}
+	})
+
+	t.Run("legacy_user", func(t *testing.T) {
+		t.Parallel()
+
+		if _, err := CompileAndAuthorize(LegacyRealmAdmin, []Permission{LegacyRealmUser}); err != nil {
+			t.Error(err)
+		}
+	})
+
+	t.Run("escalate", func(t *testing.T) {
+		t.Parallel()
+
+		if _, err := CompileAndAuthorize(UserRead|UserWrite, []Permission{16383}); err == nil {
+			t.Errorf("expected error")
+		}
+	})
 }
 
 func TestImpliedBy(t *testing.T) {

programming_language: Go