OFFLINE
Awaiting data
Security intelligence
MajorCritical vulnerability

CVE-2026-107728: Strawberry GraphQL: Synchronous permission checks can treat an awaitable authorization result as truthy

GitHub Advisories · officialPublished Oct 9, 2026Risk 37/100

### 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.

Upgrade affected packages to a patched version: strawberry-graphql 0.326.1.

Vendor
Not specified
Product
strawberry-graphql
Exploitation
none known
Evidence
official
CVSS
7.5

This record is attributed to GitHub Advisories. Exploitation status and remediation guidance are kept separate from the vulnerability's technical severity.

Open primary source