{"id":"CVE-2026-35442","kind":"vulnerability","aliases":["CVE-2026-35442","GHSA-38hg-ww64-rrwc"],"related":[],"title":"Directus: Authenticated Users Can Extract Concealed Fields via Aggregate Queries","description":"### Summary\n\nAggregate functions (`min`, `max`) applied to fields with the `conceal` special type incorrectly return raw database values instead of the masked placeholder. When combined with `groupBy`, any authenticated user with read access to the affected collection can extract concealed field values, including static API tokens and two-factor authentication secrets from `directus_users`.\n\n### Details\n\nFields marked with `conceal` are protected by payload processing logic that replaces real values with a masked placeholder on read. This protection works correctly for standard item queries, but aggregate query results are structured differently, operations are nested under their function name rather than appearing as flat field keys. The masking logic does not account for this nested structure, causing it to silently skip concealed fields in aggregate responses and return their raw values to the client.\n\n### Impact\n\n- **Account Takeover** An authenticated attacker can harvest static API tokens for all users, including administrators, enabling immediate authentication as any account without credentials.\n\n- **2FA Bypass** TOTP seeds stored in directus_users can similarly be extracted, allowing an attacker to bypass two-factor authentication for any account.","summary":"Directus hides fields marked with the conceal type on normal reads, but aggregate min and max queries with groupBy return their raw values. An logged-in user with read access to the collection can pull static API tokens and two-factor secrets from directus_users, then take over other accounts.","severity":"high","cvss":8.1,"epss":0.00343,"exploited":false,"exploited_at":null,"products":[{"name":"directus","fixed":["11.17.0"],"affected":"< 11.17.0","ecosystem":"npm"},{"name":"monospace directus","fixed":["11.17.0"],"affected":"< 11.17.0","ecosystem":"vendor"}],"ecosystems":["npm","vendor"],"tags":["api","cwe-200","cwe-863","directus","node","package","self-hosted"],"not_affected_if":["no-authenticated-users-with-read-access","version-11.17.0-or-later"],"how_to_check":"- Check the installed version with `npm ls directus` or `npx directus --version`, and compare it to the fixed version.\n- Look for collections containing fields with the `conceal` special type, especially in directus_users.\n- Review which roles have read access to collections that include concealed fields.","fix":"- directus: upgrade to `11.17.0` or later","status":"open","published_at":"2026-04-04T06:13:57+00:00","first_seen_at":"2026-11-09T01:44:56+00:00","triaged_at":"2026-11-09T01:46:36+00:00","updated_at":"2026-11-09T01:54:15+00:00","category":"package","confidence":0.85,"triage":{"at":"2026-11-09T01:46:36Z","model":"claude-haiku-5-5","output":{"fix":"- directus: upgrade to `11.17.0` or later","reach":"internet","title":"Directus: aggregate queries leak concealed fields like API tokens and 2FA seeds","impact":"high","summary":"Directus hides fields marked with the conceal type on normal reads, but aggregate min and max queries with groupBy return their raw values. An logged-in user with read access to the collection can pull static API tokens and two-factor secrets from directus_users, then take over other accounts.","audience":"businesses","category":"package","nicknames":[],"who_cares":["directus","self-hosted","node","api"],"confidence":0.85,"fix_status":"available","needs_auth":"yes","worst_case":"Attacker takes over any account, including administrators, and bypasses 2FA","analyst_note":"","how_to_check":"- Check the installed version with `npm ls directus` or `npx directus --version`, and compare it to the fixed version.\n- Look for collections containing fields with the `conceal` special type, especially in directus_users.\n- Review which roles have read access to collections that include concealed fields.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["version-11.17.0-or-later","no-authenticated-users-with-read-access"],"who_is_affected":"Directus instances below 11.17.0 where some users hold read access to a collection with concealed fields. Directus's own user table holds static tokens and TOTP seeds, so any authenticated user with read access to directus_users is exposed. Instances where users are only trusted administrators or have no read access to concealed collections carry less risk, but the fix still applies.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"no","severity_if_unknown":"high"},"cost_usd":0.000779,"input_tokens":4912,"output_tokens":576,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-200':27B '-2026':12A,20A '-35442':13A,21A '-863':29B '2fa':245C '38hg':16A 'access':66B,120C 'account':87B,198C,222C,242C,268C 'administr':236C 'affect':123C 'aggreg':9A,48B,89C,173C,211C 'allow':257C 'api':25B,73B,132C,230C 'appear':188C 'appli':93C 'attack':226C,259C 'authent':2A,116C,138C,225C,239C,265C 'bypass':246C,261C 'caus':203C 'client':220C 'collect':69B,124C 'combin':112C 'conceal':6A,42B,98C,127C,147C,208C 'correct':167C 'credenti':244C 'cve':11A,19A 'cwe':26B,28B 'databas':104C 'detail':143C 'differ':178C 'directus':1A,22A,24A,30B,36B,81B,141C,251C 'enabl':237C 'extract':5A,126C,256C 'factor':78B,137C,264C 'field':7A,38B,95C,128C,144C,191C,209C 'flat':190C 'function':90C,184C 'ghsa':15A 'ghsa-38hg-ww64-rrwc':14A 'groupbi':54B,114C 'harvest':228C 'hide':37B 'host':35B 'immedi':238C 'impact':221C 'includ':130C,235C 'incorrect':101C 'instead':106C 'item':170C 'key':192C 'log':61B 'logged-in':60B 'logic':153C,195C 'mark':39B,145C 'mask':109C,160C,194C 'max':51B,92C 'min':49B,91C 'monospace':23A 'name':185C 'nest':181C,201C 'node':31B 'normal':45B 'oper':179C 'packag':32B 'payload':151C 'placehold':110C,161C 'process':152C 'protect':149C,165C 'pull':71B 'queri':10A,52B,171C,174C 'rather':186C 'raw':57B,103C,216C 'read':46B,65B,119C,163C 'real':156C 'replac':155C 'respons':212C 'result':175C 'return':55B,102C,214C 'rrwc':18A 'secret':79B,139C 'seed':248C 'self':34B 'self-host':33B 'silent':206C 'similar':254C 'skip':207C 'special':99C 'standard':169C 'static':72B,131C,229C 'store':249C 'structur':177C,202C 'summari':88C 'take':84B 'takeov':223C 'token':74B,133C,231C 'totp':247C 'two':77B,136C,263C 'two-factor':76B,135C,262C 'type':43B,100C 'user':3A,63B,82B,117C,142C,234C,252C 'valu':58B,105C,129C,157C,217C 'via':8A 'without':243C 'work':166C 'ww64':17A","nicknames":[],"mitigations":[],"who_affected":"Directus instances below 11.17.0 where some users hold read access to a collection with concealed fields. Directus's own user table holds static tokens and TOTP seeds, so any authenticated user with read access to directus_users is exposed. Instances where users are only trusted administrators or have no read access to concealed collections carry less risk, but the fix still applies.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["directus","monospacedirectus"],"ptokens":["directus","monospace"],"labels":["api","cwe200","cwe863","directus","high","node","npm","package","selfhosted","vendor"],"campaign_type":null,"search_a":"'-2026':12A,20A '-35442':13A,21A '38hg':16A 'aggreg':9A 'authent':2A 'conceal':6A 'cve':11A,19A 'directus':1A,22A,24A 'extract':5A 'field':7A 'ghsa':15A 'ghsa-38hg-ww64-rrwc':14A 'monospace':23A 'queri':10A 'rrwc':18A 'user':3A 'via':8A 'ww64':17A","search_b":"'-200':27B '-863':29B 'access':66B 'account':87B 'aggreg':48B 'api':25B,73B 'collect':69B 'conceal':42B 'cwe':26B,28B 'directus':30B,36B,81B 'factor':78B 'field':38B 'groupbi':54B 'hide':37B 'host':35B 'log':61B 'logged-in':60B 'mark':39B 'max':51B 'min':49B 'node':31B 'normal':45B 'packag':32B 'pull':71B 'queri':52B 'raw':57B 'read':46B,65B 'return':55B 'secret':79B 'self':34B 'self-host':33B 'static':72B 'take':84B 'token':74B 'two':77B 'two-factor':76B 'type':43B 'user':63B,82B 'valu':58B","search_c":"'2fa':245C 'access':120C 'account':198C,222C,242C,268C 'administr':236C 'affect':123C 'aggreg':89C,173C,211C 'allow':257C 'api':132C,230C 'appear':188C 'appli':93C 'attack':226C,259C 'authent':116C,138C,225C,239C,265C 'bypass':246C,261C 'caus':203C 'client':220C 'collect':124C 'combin':112C 'conceal':98C,127C,147C,208C 'correct':167C 'credenti':244C 'databas':104C 'detail':143C 'differ':178C 'directus':141C,251C 'enabl':237C 'extract':126C,256C 'factor':137C,264C 'field':95C,128C,144C,191C,209C 'flat':190C 'function':90C,184C 'groupbi':114C 'harvest':228C 'immedi':238C 'impact':221C 'includ':130C,235C 'incorrect':101C 'instead':106C 'item':170C 'key':192C 'logic':153C,195C 'mark':145C 'mask':109C,160C,194C 'max':92C 'min':91C 'name':185C 'nest':181C,201C 'oper':179C 'payload':151C 'placehold':110C,161C 'process':152C 'protect':149C,165C 'queri':171C,174C 'rather':186C 'raw':103C,216C 'read':119C,163C 'real':156C 'replac':155C 'respons':212C 'result':175C 'return':102C,214C 'secret':139C 'seed':248C 'silent':206C 'similar':254C 'skip':207C 'special':99C 'standard':169C 'static':131C,229C 'store':249C 'structur':177C,202C 'summari':88C 'takeov':223C 'token':133C,231C 'totp':247C 'two':136C,263C 'two-factor':135C,262C 'type':100C 'user':117C,142C,234C,252C 'valu':105C,129C,157C,217C 'without':243C 'work':166C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-04-02T16:44:49+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-38hg-ww64-rrwc","url":"https://github.com/advisories/GHSA-38hg-ww64-rrwc","severity":"high","published_at":"2026-04-04T06:13:57+00:00","modified_at":"2026-11-09T01:41:55+00:00","first_seen_at":"2026-11-09T01:44:56+00:00","fetched_at":"2026-11-09T01:47:43+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-35442","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-35442","severity":null,"published_at":"2026-04-06T22:16:22+00:00","modified_at":"2026-07-24T21:10:00+00:00","first_seen_at":"2026-11-09T01:54:15+00:00","fetched_at":"2026-11-09T01:54:15+00:00","note":null}],"documents":[{"id":105070,"url":"https://api.github.com/repos/directus/directus/security-advisories/GHSA-38hg-ww64-rrwc","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":105071,"url":"https://github.com/directus/directus/security/advisories/GHSA-38hg-ww64-rrwc","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2026-04-02T16:44:49+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"}],"disclosures":[],"exploit_sources":[{"type":"epss","score":0.00343,"url":"https://api.first.org/data/v1/epss?cve=CVE-2026-35442"}],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}