Strawberry GraphQL Permission Bypass via Awaitable Truthiness
Strawberry GraphQL's PermissionExtension incorrectly handles synchronous custom permission checks that return awaitable objects, allowing unauthorized access to protected fields due to Python's truthy evaluation of unawaited coroutines.
CVE search metadata
CVE search record: CVE-2026-107728. Severity: high. CVSS: 7.5. EPSS: 0.35%. KEV: no. Product: strawberry-graphql (0.217.0 - 0.326.0). Brief: Strawberry GraphQL Permission Bypass via Awaitable Truthiness. Brief link: https://feed.craftedsignal.io/briefs/2026-10-strawberry-graphql-bypass/
Strawberry GraphQL (versions 0.217.0 through 0.326.0) contains an authorization bypass vulnerability within PermissionExtension.resolve() in strawberry/permission.py. When a developer defines a custom permission class with a has_permission method using a standard def (instead of async def) that returns an awaitable result (such as a coroutine), the framework fails to await the result or check its resolved value. Because Python evaluates an unawaited awaitable object as truthy, the authorization check unconditionally grants access, bypassing intended security controls on the protected GraphQL field.
This issue affects any application using custom permission classes where has_permission does not return a direct boolean or utilize async def. Standard async def permissions or those returning explicit boolean values remain unaffected. The flaw impacts both execute_sync() and execute() paths for fields utilizing synchronous resolvers.
Attack Chain
- Attacker identifies a GraphQL field protected by a custom
strawberry.permission.BasePermissionclass. - The custom permission class is misconfigured such that
has_permissionis defined as a synchronousdefthat returns a coroutine object rather than a boolean. - Attacker sends a standard GraphQL query requesting data from the protected field.
- The Strawberry GraphQL engine invokes
PermissionExtension.resolve()during the resolution of the requested field. PermissionExtension.resolve()checks the truthiness of the returned object fromhas_permission().- Python evaluates the unawaited coroutine as
True(truthy). - The framework treats the authorization as granted, bypassing the logic intended to block the request.
- The underlying field resolver is executed, and the sensitive data is returned in the GraphQL response to the attacker.
Impact
Successful exploitation results in unauthorized access to GraphQL fields intended to be protected by custom permission logic. This may lead to the exposure of sensitive data, unauthorized state changes, or the bypass of business logic checks, depending on what the specific permission-protected resolver performs. The impact is limited to applications that implement custom permission classes matching the vulnerable has_permission function signature.
Recommendation
Prioritize auditing custom permission classes within your Strawberry GraphQL implementation to identify any has_permission definitions that return awaitables rather than explicit boolean values.
- Upgrade
strawberry-graphqlto a version containing the fix for CVE-2026-107728. - Review all classes inheriting from
strawberry.permission.BasePermissionto ensurehas_permissionfunctions are either standard methods returning booleans or are explicitly defined asasync deffor asynchronous logic. - If using asynchronous logic, verify that the application properly utilizes
resolve_async()or ensure all permission checks are correctly awaited before boolean evaluation.
Immediate actions
Upgrade strawberry-graphql to 0.326.1 or later
Mitigations
Review custom BasePermission subclasses for synchronous methods returning awaitables.
CVE-2026-107728