CVE-2026-107728: Strawberry GraphQL: Synchronous permission checks can treat an awaitable authorization result as truthy
### Summary `PermissionExtension.resolve()` evaluates the return value of `has_permission()` for truthiness on the synchronous path. `supports_sync` only classifies a permission as asynchronous when `has_permission` is declared with `async def` (via `inspect.iscoroutinefunction`), so a plain `def` that returns an awaitable is treated as synchronous. An awaitable is always truthy, so the check passes even when it resolves to `False` and the protected resolver runs. The resolve path is chosen by the field resolver, not by the execution method, so any field with a synchronous resolver is affected under both `execute_sync()` and `execute()`. Permissions declared with `async def has_permission()`, or a plain `def` returning a boolean, are not affected. ### Details The affected code is `PermissionExtension.resolve()` in `strawberry/permission.py`. A permission attached to a field whose `has_permission` is a normal `def` returning an awaitable reaches this path; the awaitable is never awaited and its truthiness grants access. `resolve_async()` is not affected because it uses `await_maybe()`. ### PoC ```python import strawberry from strawberry.permission import BasePermission class DenyViaAwaitable(BasePermission): message = "denied" def has_permission(self, source, info, **kwargs): async def result(): return False return result() @strawberry.type class Query: @strawberry.field(permission_classes=[DenyViaAwaitable]) def secret(self) -> str: return "secret" schema = strawberry.Schema(Query) print(schema.execute_sync("{ secret }").data) # {'secret': 'secret'} instead of a permission error ``` ### Impact An application using a custom permission whose `has_permission` is a normal `def` returning an awaitable can unintentionally grant access to the protected field. Standard permissions (a `def` returning a boolean, or an `async def`) are not affected, so exploitability depends on the application using this specific permission shape. ### Fix The synchronous path now fails closed: if `has_permission()` returns an awaitable, an error is raised instead of granting access.
Recommended action
Recommended action
Upgrade affected packages to a patched version: strawberry-graphql 0.326.1.
Technical details
- Vendor
- Not specified
- Product
- strawberry-graphql
- Exploitation
- none known
- Evidence
- official
Evidence and sources
This record is attributed to GitHub Advisories. Exploitation status and remediation guidance are kept separate from the vulnerability's technical severity.
Open primary source