{"schema":"threatline.record/2","record":{"id":"CVE-2026-107728","aliases":["GHSA-pfvf-fwfp-25mp","PYSEC-2026-4303"],"summary":"Strawberry GraphQL: Synchronous permission checks can treat an awaitable authorization result as truthy","details":"### Summary\n\n`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.\n\nThe 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.\n\n### Details\n\nThe 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()`.\n\n### PoC\n\n```python\nimport strawberry\nfrom strawberry.permission import BasePermission\n\n\nclass DenyViaAwaitable(BasePermission):\n    message = \"denied\"\n\n    def has_permission(self, source, info, **kwargs):\n        async def result():\n            return False\n\n        return result()\n\n\n@strawberry.type\nclass Query:\n    @strawberry.field(permission_classes=[DenyViaAwaitable])\n    def secret(self) -> str:\n        return \"secret\"\n\n\nschema = strawberry.Schema(Query)\nprint(schema.execute_sync(\"{ secret }\").data)  # {'secret': 'secret'} instead of a permission error\n```\n\n### Impact\n\nAn 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.\n\n### Fix\n\nThe synchronous path now fails closed: if `has_permission()` returns an awaitable, an error is raised instead of granting access.","categories":["Libraries & packages"],"product":"strawberry-graphql","vendor":"strawberry-graphql","ecosystem":"pip","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-pfvf-fwfp-25mp","source_modified_at":"2026-10-09T14:07:19Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"strawberry-graphql"},"range":">= 0.217.0, <= 0.326.0"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-107728","source_modified_at":"2026-10-14T01:31:32.335Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"strawberry","vendor":"strawberry-graphql","versions":[{"version":">= 0.217.0, < 0.326.1","status":"affected"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-pfvf-fwfp-25mp","source_modified_at":"2026-10-15T14:55:39.004006266Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"PyPI","name":"strawberry-graphql","purl":"pkg:pypi/strawberry-graphql"},"ranges":[{"events":[{"introduced":"0.217.0"},{"fixed":"0.326.1"}],"type":"ECOSYSTEM"}],"versions":["0.217.0","0.217.1","0.218.0","0.218.0.dev1705418681","0.218.1","0.219.0","0.219.1","0.219.2","0.220.0","0.220.0.dev1709543239","0.221.0","0.221.0.dev1710955937","0.221.1","0.222.0","0.223.0","0.224.0","0.224.0.dev1711748192","0.224.1","0.224.2","0.225.0","0.225.1","0.226.0","0.226.1","0.226.2","0.227.0","0.227.0.dev1713463204","0.227.0.dev1713475585","0.227.1","0.227.2","0.227.3","0.227.4","0.227.5","0.227.6","0.227.7","0.228.0","0.228.0.dev1713643365","0.229.0","0.229.1","0.229.2","0.229.2.dev1715873118","0.229.2.dev1715881453","0.230.0","0.230.0.dev1716318708","0.231.0","0.231.1","0.232.0","0.232.1","0.232.2","0.233.0","0.233.1"]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-pfvf-fwfp-25mp","source_modified_at":"2026-10-09T14:07:19Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"pip","name":"strawberry-graphql"},"version":"0.326.1"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-pfvf-fwfp-25mp","source_modified_at":"2026-10-15T14:55:39.004006266Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"PyPI","name":"strawberry-graphql","purl":"pkg:pypi/strawberry-graphql"},"version":"0.326.1"}],"cvss":7.5,"severity":"High","kev":{"listed":false},"epss":{"probability":0.00353,"percentile":0.27793,"score_date":"2026-10-23"},"published_at":"2026-10-08T22:13:00.911Z","modified_at":"2026-10-15T14:55:39.004006266Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-pfvf-fwfp-25mp","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-09T14:07:19Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-107728","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-14T01:31:32.335Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-pfvf-fwfp-25mp","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-15T14:55:39.004006266Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-107728","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/strawberry-graphql/strawberry/security/advisories/GHSA-pfvf-fwfp-25mp","tags":["exploit"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-107728","source":"GitHub Advisory Database"},{"source":"CVE List","url":"https://github.com/strawberry-graphql/strawberry/pull/4605","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/strawberry-graphql/strawberry/commit/2ebb79796c0e5ebb43cae1abd2b5a21363b1c00e","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/strawberry-graphql/strawberry/releases/tag/0.326.1","tags":["x_refsource_MISC"]},{"url":"https://github.com/advisories/GHSA-pfvf-fwfp-25mp","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"poc","automatable":"yes","technical_impact":"partial","assessed_at":"2026-10-14T01:30:43.898409Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-15T14:55:39.004006266Z","content_hash":"9388d69eaf988211913a1dded2adb376b6bf19b1dcc552dff32b52191678ece8"}}
