<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/static/style.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Most recent entries from all</title>
    <link>https://vulnerability.circl.lu</link>
    <description>Contains only the most 10 recent entries.</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Sat, 10 Oct 2026 12:09:42 +0000</lastBuildDate>
    <item>
      <title>fkie_cve-2026-107728</title>
      <link>https://vulnerability.circl.lu/vuln/fkie_cve-2026-107728</link>
      <description>&lt;p&gt;Strawberry GraphQL is a library for creating GraphQL APIs. From 0.217.0 until 0.326.1, PermissionExtension.resolve() on a synchronous field resolver evaluates the result of has_permission() for truthiness. When a custom permission declares has_permission() as a normal function but returns an awaitable, supports_sync does not classify it as asynchronous, the awaitable is not awaited, and its inherently truthy object value permits the protected resolver to run even when the result would resolve to false. This affects synchronous field resolvers under both execute_sync() and execute(); permissions declared with async def has_permission() and synchronous permissions returning a boolean are not affected. This issue is fixed in version 0.326.1.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Strawberry GraphQL is a library for creating GraphQL APIs. From 0.217.0 until 0.326.1, PermissionExtension.resolve() on a synchronous field resolver evaluates the result of has_permission() for truthiness. When a custom permission declares has_permission() as a normal function but returns an awaitable, supports_sync does not classify it as asynchronous, the awaitable is not awaited, and its inherently truthy object value permits the protected resolver to run even when the result would resolve to false. This affects synchronous field resolvers under both execute_sync() and execute(); permissions declared with async def has_permission() and synchronous permissions returning a boolean are not affected. This issue is fixed in version 0.326.1.&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/fkie_cve-2026-107728</guid>
    </item>
    <item>
      <title>GHSA-pfvf-fwfp-25mp — Strawberry GraphQL: Synchronous permission checks can treat an awaitable authorization result as truthy</title>
      <link>https://vulnerability.circl.lu/vuln/ghsa-pfvf-fwfp-25mp</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; PyPI: strawberry-graphql&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;`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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;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()`.&lt;/p&gt;
&lt;p&gt;### PoC&lt;/p&gt;
&lt;p&gt;```python
import strawberry
from strawberry.permission import BasePermission&lt;/p&gt;
&lt;p&gt;class DenyViaAwaitable(BasePermission):
    message = &amp;#34;denied&amp;#34;&lt;/p&gt;
&lt;p&gt;def has_permission(self, source, info, **kwargs):
        async def result():
            return False&lt;/p&gt;
&lt;p&gt;return result()&lt;/p&gt;
&lt;p&gt;@strawberry.type
class Query:
    @strawberry.field(permission_classes=[DenyViaAwaitable])
    def secret(…&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; PyPI: strawberry-graphql&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;`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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;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()`.&lt;/p&gt;
&lt;p&gt;### PoC&lt;/p&gt;
&lt;p&gt;```python
import strawberry
from strawberry.permission import BasePermission&lt;/p&gt;
&lt;p&gt;class DenyViaAwaitable(BasePermission):
    message = &amp;#34;denied&amp;#34;&lt;/p&gt;
&lt;p&gt;def has_permission(self, source, info, **kwargs):
        async def result():
            return False&lt;/p&gt;
&lt;p&gt;return result()&lt;/p&gt;
&lt;p&gt;@strawberry.type
class Query:
    @strawberry.field(permission_classes=[DenyViaAwaitable])
    def secret(…&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/ghsa-pfvf-fwfp-25mp</guid>
    </item>
  </channel>
</rss>
