Moderate severityNVD Advisory· Published Mar 23, 2023· Updated Feb 21, 2025
directus vulnerable to Insertion of Sensitive Information into Log File
CVE-2023-28443
Description
Directus is a real-time API and App dashboard for managing SQL database content. Prior to version 9.23.3, the directus_refresh_token is not redacted properly from the log outputs and can be used to impersonate users without their permission. This issue is patched in version 9.23.3.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
directusnpm | < 9.23.3 | 9.23.3 |
Affected products
1Patches
1349536303983Merge pull request from GHSA-8vg2-wf3q-mwv7
3 files changed · +67 −2
api/src/logger.ts+18 −2 modified@@ -1,11 +1,12 @@ import { toArray } from '@directus/shared/utils'; -import type { Request, RequestHandler } from 'express'; import { merge } from 'lodash'; -import pino, { LoggerOptions } from 'pino'; +import pino, { LoggerOptions, SerializedResponse } from 'pino'; +import type { Request, RequestHandler } from 'express'; import pinoHTTP, { stdSerializers } from 'pino-http'; import { URL } from 'url'; import env from './env'; import { getConfigFromEnv } from './utils/get-config-from-env'; +import { redactHeaderCookie } from './utils/redact-header-cookies'; const pinoOptions: LoggerOptions = { level: env.LOG_LEVEL || 'info', @@ -86,8 +87,23 @@ export const expressLogger = pinoHTTP({ req(request: Request) { const output = stdSerializers.req(request); output.url = redactQuery(output.url); + if (output.headers?.cookie) { + output.headers.cookie = redactHeaderCookie(output.headers.cookie, [ + 'access_token', + `${env.REFRESH_TOKEN_COOKIE_NAME}`, + ]); + } return output; }, + res(response: SerializedResponse) { + if (response.headers?.['set-cookie']) { + response.headers['set-cookie'] = redactHeaderCookie(response.headers['set-cookie'], [ + 'access_token', + `${env.REFRESH_TOKEN_COOKIE_NAME}`, + ]); + } + return response; + }, }, }) as RequestHandler;
api/src/utils/redact-header-cookies.test.ts+42 −0 added@@ -0,0 +1,42 @@ +import { describe, expect, test } from 'vitest'; +import env from '../env'; +import { redactHeaderCookie } from './redact-header-cookies'; + +describe('redactHeaderCookie', () => { + describe('Given auth cookies', () => { + test('When it finds a refresh_token, it should redact the value', () => { + const tokenKey = env.REFRESH_TOKEN_COOKIE_NAME; + const cookieHeader = `${tokenKey}=shh;`; + const cookieNames = [`${tokenKey}`]; + + const redactedCookie = redactHeaderCookie(cookieHeader, cookieNames); + expect(redactedCookie).toBe(`${tokenKey}=--redacted--;`); + }); + test('When it finds an access_token, it should redact the value', () => { + const tokenKey = 'access_token'; + const cookieHeader = `${tokenKey}=secret;`; + const cookieNames = [`${tokenKey}`]; + + const redactedCookie = redactHeaderCookie(cookieHeader, cookieNames); + expect(redactedCookie).toBe(`${tokenKey}=--redacted--;`); + }); + test('When it finds both an access_token and refresh_token, it should redact both values', () => { + const cookieHeader = `access_token=secret; ${env.REFRESH_TOKEN_COOKIE_NAME}=shhhhhhh; randomCookie=Erdtree;`; + const cookieNames = ['access_token', `${env.REFRESH_TOKEN_COOKIE_NAME}`]; + + const redactedCookie = redactHeaderCookie(cookieHeader, cookieNames); + expect(redactedCookie).toBe( + `access_token=--redacted--; ${env.REFRESH_TOKEN_COOKIE_NAME}=--redacted--; randomCookie=Erdtree;` + ); + }); + }); + describe('Given negligible cookies', () => { + test('It should return the orignal value', () => { + const originalCookie = `Crown=Swords; Hail=Sithis;`; + const cookieNames = [env.REFRESH_TOKEN_COOKIE_NAME, 'access_token']; + + const redactedCookie = redactHeaderCookie(originalCookie, cookieNames); + expect(redactedCookie).toBe(originalCookie); + }); + }); +});
api/src/utils/redact-header-cookies.ts+7 −0 added@@ -0,0 +1,7 @@ +export function redactHeaderCookie(cookieHeader: string, cookieNames: string[]) { + for (const cookieName of cookieNames) { + const re = new RegExp(`(${cookieName}=)([^;]+)`); + cookieHeader = cookieHeader.replace(re, `$1--redacted--`); + } + return cookieHeader; +}
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-8vg2-wf3q-mwv7ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-28443ghsaADVISORY
- github.com/directus/directus/blob/7c479c5161639aac466c763b6b958a9524201d74/api/src/logger.tsghsax_refsource_MISCWEB
- github.com/directus/directus/commit/349536303983ccba68ecb3e4fb35315424011afcghsax_refsource_MISCWEB
- github.com/directus/directus/security/advisories/GHSA-8vg2-wf3q-mwv7ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.