Keystone is a popular open-source headless CMS for Node.js, designed to make it easy for developers to build powerful and flexible backend applications. It’s built with GraphQL and React, and is widely used to manage dynamic content. Recently, a vulnerability was identified and tracked as CVE-2023-40027. This issue puts some Keystone projects at risk by unintentionally exposing sensitive admin metadata to the public. In this post, we'll dive into what happened, who’s affected, how you can fix or avoid this issue, and see some code examples to make things clear and practical.

What is CVE-2023-40027?

The vulnerability occurs when the ui.isAccessAllowed property in a Keystone project is set to undefined. In this scenario, the adminMeta GraphQL query is accessible without authentication. This means anyone, even if they aren’t logged in, can obtain potentially sensitive admin interface metadata.

Normally, Keystone restricts admin access based on authentication sessions. However, due to this flaw, some developers believed defining a session strategy would automatically protect admin routes—but that’s not always the case.

Key points

- If you use a @keystone-6/auth package or define your own ui.isAccessAllowed, you are not affected.
- If you rely only on a session strategy (and leave ui.isAccessAllowed as undefined), you are vulnerable.

Session Strategy: Used to authenticate users’ requests.

2. ui.isAccessAllowed: Optional, custom function letting you decide who can access the UI based on session data.

By default, people may assume that just adding a session strategy is enough to enforce that only logged-in users can make sensitive admin queries. The default AdminUI middleware respects the session, but the mechanism for the adminMeta GraphQL API doesn’t check the session if ui.isAccessAllowed is undefined. As a result, the metadata becomes public.

Let’s say you have the following basic Keystone config

// keystone.js (VULNERABLE)
import { config } from '@keystone-6/core';

export default config({
  db: { provider: 'sqlite', url: 'file:./keystone.db' },
  // session strategy is defined
  session: { /* your session config here */ },
  lists: { /* your lists */ },
  // Notice: 'ui.isAccessAllowed' is undefined!
});

If you now spin up this Keystone app, anyone (even unauthenticated users) can query the following GraphQL API:

query {
  adminMeta {
    lists {
      key
      fields {
        path
        fieldMeta {
          isOrderable
        }
      }
    }
  }
}

This returns detailed information about all your backend lists and fields. While not your user data, metadata about your admin schema can help an attacker map out your system for further attacks.

Start a new Keystone project using the vulnerable setup.

2. Open GraphQL Playground at http://localhost:300/api/graphql.

Run the adminMeta query (no need to log in)

query {
  adminMeta {
    lists {
      key
      fields {
        path
      }
    }
  }
}

Result: You’ll get all schema metadata with no authentication.

Upgrade to the Latest Version

This vulnerability is fixed in @keystone-6/core@5.5.1. Keystone patched this by ensuring proper checks for isAccessAllowed or by falling back to session validation.

npm install @keystone-6/core@^5.5.1

Define Your Own Access Function (Workaround)

If you can’t upgrade, explicitly set ui.isAccessAllowed in your config. Here’s a safe boilerplate:

// keystone.js (PATCHED)
import { config } from '@keystone-6/core';

export default config({
  db: { provider: 'sqlite', url: 'file:./keystone.db' },
  session: { /* your session config here */ },
  lists: { /* your lists */ },
  ui: {
    // Only allow logged-in users access to Admin UI
    isAccessAllowed: ({ session }) => !!session?.itemId,
  },
});

Replace itemId with whatever identifies your logged-in admin user in your session.

Who’s Safe?

- Using @keystone-6/auth? ✔️ Safe by default.

All others? ❗ Vulnerable until you upgrade or patch.

## Learn More / References

- Official GitHub Security Advisory
- Keystone 6 changelog for v5.5.1
- Keystone Docs: Writing your own isAccessAllowed
- NIST NVD entry for CVE-2023-40027

Conclusion

CVE-2023-40027 is a great example of why it’s important to understand the default behaviors in frameworks—even the most popular open-source projects can surprise you with corner cases. If you use Keystone CMS, check your config today. Upgrading to the latest version or defining your own ui.isAccessAllowed is the best way to lock down your admin API.

Stay updated and keep your admin interfaces private! If you have any doubts, check the references above or reach out to the Keystone community for help.

Timeline

Published on: 08/15/2023 18:15:00 UTC
Last modified on: 08/23/2023 00:04:00 UTC