Keystone is a popular, modern headless CMS built for Node.js applications, leveraging technologies like GraphQL and React. In late 2022, a severe vulnerability — CVE-2022-39382 — was identified in the @keystone-6/core package, versions 3.. and 3..1. This issue can quietly undermine crucial security controls on your production server if you make decisions based on the NODE_ENV variable in your code.
Let’s deeply examine what happened, how it works (with clear code examples), the risk, and how to stay protected—even if you don’t consider yourself a security professional.
How Does NODE_ENV Matter in Node.js and Keystone?
The environment variable NODE_ENV is used across most Node.js apps and their dependencies. The conventional use looks like this:
if (process.env.NODE_ENV === "production") {
enableProductionSecurity();
} else {
enableDebugMode();
}
In production (NODE_ENV=production), you enable all the security hardening your app needs.
Keystone and its user code as well as many other libraries use NODE_ENV to decide when to disable debug routes, use secure cookies, suppress detailed errors, and much more.
What Exactly Was the Flaw?
If you used user code inside your Keystone project that relies on NODE_ENV for enabling or disabling security-sensitive features, you were at risk.
The bug:
When Keystone compiled user code, it always replaced (inlined) process.env.NODE_ENV with the string "development" inside your user code—even if, in the real environment, you set NODE_ENV=production before running the app.
This means
- Any if (process.env.NODE_ENV === "production") check in your code will always behave as if it’s in development mode, even when actually live.
Security checks and optimizations intended for production are never activated.
Note: Keystone’s own core and its third-party dependencies were not affected—the problem was only in code bundled as part of your Keystone project.
Imagine you wrote the following logic in your custom Keystone code
const sessionOptions = process.env.NODE_ENV === "production"
? { secure: true, sameSite: "strict" }
: { secure: false, sameSite: "lax" };
// sessionOptions used in cookie/session setup
Even when running on production and setting NODE_ENV=production, due to this bug, sessionOptions would always use { secure: false, sameSite: "lax" } — the weak, debug-only settings!
Which versions?
Only @keystone-6/core@3.. and 3..1 are affected. Later versions fixed the inlining bug.
Are you safe?
- If you set NODE_ENV and rely on it in your user code for production security, you’re vulnerable.
if (process.env.NODE_ENV === "production") {
// Enable CSP, secure cookies, hide errors, etc.
`
- If the inlined code (in .next or built output) contains "development" as a hard-coded value, instead of referencing the real environment variable, you’re likely affected.
See verbose error messages (good for finding further vulnerabilities)
- This is particularly dangerous for multi-tenant apps, e-commerce, or systems that process private data.
*Why is this so insidious?*
Because everything looks normal—you deploy with NODE_ENV=production, but your user code acts as if it’s permanent dev mode.
The Official Fix
Fixed in @keystone-6/core@3..2
All users should upgrade ASAP.
- Patch and regression tests were added in GitHub Pull Request #8063
- Now, user code built and executed with NODE_ENV=production correctly reads the real environment variable
If you can’t upgrade:
Remove or explicitly control logic, or only rely on top-level cross-cutting settings.
- Consider running security headers/cookie settings *independently* of Keystone’s code until you can patch.
Key References & Further Reading
- GitHub Advisory for CVE-2022-39382
- Keystone PR: Fix NODE_ENV in user code regression
- NPM Advisory
- Keystone Changelog
Summary Table
| Version | Vulnerable? | Safe? |
|------------------|------------------|-----------------------|
| 3.. | :x: | |
| 3..1 | :x: | |
| 3..2+ | | :white_check_mark: |
Audit your Keystone version.
Run npm ls @keystone-6/core to check.
- Upgrade to @keystone-6/core@3..2 or later immediately.
- Review your use of process.env.NODE_ENV in your app and make sure security logic depends only on trustworthy environment reads.
- Never assume your code’s execution environment by compile time—always verify at runtime, where possible.
Stay safe, and always test security critical flows after every dependency upgrade or config tweak!
If you want more in-depth help with Keystone security or how best to architect production-grade Node.js apps, reach out or follow Keystone’s security updates.
*Article written exclusively for you, covering the real-world impact and prevention for CVE-2022-39382 — because your CMS deserves true production security, not just a good enough guess.*
Timeline
Published on: 11/03/2022 14:15:00 UTC
Last modified on: 11/04/2022 16:08:00 UTC