Skip to content

Require verified email for all authorization gates, not just domain trust#5366

Open
gn00295120 wants to merge 1 commit into
google:masterfrom
gn00295120:fix/require-email-verified-for-all-authz-gates
Open

Require verified email for all authorization gates, not just domain trust#5366
gn00295120 wants to merge 1 commit into
google:masterfrom
gn00295120:fix/require-email-verified-for-all-authz-gates

Conversation

@gn00295120

Copy link
Copy Markdown

Summary

PR #5314 (e68fd259ca) correctly required email_verified for domain-allowlist trust (_is_trusted_domain_user) to prevent GitHub Enterprise Managed Users (EMU) from asserting an arbitrary unverified email to gain whitelisted-domain access.

However, the same unverified email was still trusted by several other authorization paths in get_access() and can_user_access_testcase():

Gate Location Risk
_is_privileged_user(email) access.py:141 Full privileged access to all endpoints
is_job_allowed_for_user(email, job_type) access.py:144 Job-scoped access
is_fuzzer_allowed_for_user(email, fuzzer_name) access.py:147 Fuzzer-scoped access
testcase.uploader_email == user_email access.py:170 Embargoed testcase/reproducer read
emails_equal(user_email, issue.assignee) access.py:201 Bug-linked testcase access

An attacker controlling a GitHub Enterprise with managed users could configure an EMU account whose email matches a privileged_users entry (maintainer emails are public in commit history). Firebase would authenticate the GitHub sign-in and pass through email_verified=false. The _is_privileged_user gate would then match the asserted email against the privileged list without verifying ownership, granting full admin access — including all security-flagged test cases and embargoed crash reproducers.

Changes

src/appengine/libs/access.py:

  • get_access(): Gate _is_privileged_user, is_job_allowed_for_user, and is_fuzzer_allowed_for_user on user.email_verified. Only _is_trusted_domain_user (which already checks email_verified) remains reachable by unverified-email users.
  • can_user_access_testcase(): Gate uploader/assignee/CC/reporter email-equality checks on user.email_verified. Reuse the already-fetched user object for the _is_trusted_domain_user call (avoids a redundant auth.get_current_user() round-trip).

src/clusterfuzz/_internal/tests/appengine/libs/access_test.py:

  • test_get_access_unverified_privileged: Unverified email matching privileged_users → Denied
  • test_get_access_unverified_external_job: Unverified email with job ACL → Denied
  • test_get_access_unverified_external_fuzzer: Unverified email with fuzzer ACL → Denied
  • test_denied_unverified_uploader: Unverified email matching uploader_email → no testcase access
  • test_denied_unverified_bug_owner: Unverified email matching bug assignee → no testcase access

Backward compatibility

  • Verified-email users (Google, verified GitHub) are unaffected — email_verified defaults to True in the User namedtuple.
  • Unverified-email GitHub users (EMU) lose the ability to match privileged_users, external-user ACLs, and testcase uploader/assignee — this is the intended security hardening, consistent with the threat model established in PR Require verified email for whitelisted-domain trust #5314.

…rust

PR google#5314 (e68fd25) correctly required email_verified for domain-
allowlist trust (_is_trusted_domain_user) to prevent GitHub Enterprise
Managed Users from asserting an arbitrary unverified email to gain
whitelisted-domain access.

However, the same unverified email was still trusted by:
- _is_privileged_user (get_access line 141)
- external_users.is_job_allowed_for_user (get_access line 144)
- external_users.is_fuzzer_allowed_for_user (get_access line 147)
- testcase uploader_email equality (can_user_access_testcase line 170)
- issue assignee/CC/reporter equality (can_user_access_testcase line 201)

An attacker controlling a GitHub EMU with an unverified email matching
a privileged_users entry could obtain full privileged access to all
endpoints, security test cases, and embargoed crash reproducers.

This change gates every email-identity authorization check on
user.email_verified, consistent with the threat model established in
PR google#5314.
@gn00295120 gn00295120 requested a review from a team as a code owner July 15, 2026 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant