{"id":"CVE-2026-118772","kind":"vulnerability","aliases":["CVE-2026-118772"],"related":[],"title":"joi: email multiple option lets one long input block Node event loop","description":"joi is a schema description language and data validator for JavaScript. From 17.1.1 until 17.13.9 and 18.3.1, the Joi.string().email({ multiple: true }) rule uses a separator regular expression whose leading whitespace quantifier is retried at every position in a long whitespace run that contains no separator, causing quadratic work during String.prototype.split. The behavior applies to the default separator and every custom separator. Applications that validate attacker-controlled values with the multiple option and no effective prior length limit can have the Node.js event loop blocked for seconds by one request, preventing other work. A .max() rule is not sufficient when abortEarly: false allows the email rule to run after the maximum-length check fails. This vulnerability is fixed in versions 17.13.9 and 18.3.1.","summary":"Joi's email validator with the multiple option uses a regular expression that runs in quadratic time on long whitespace runs. A single crafted request can block the Node.js event loop for seconds, stalling other work in the server.","severity":"high","cvss":7.5,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["api","backend","javascript","joi","node.js","package"],"not_affected_if":["length-checked-first","no-multiple-option","trusted-input-only"],"how_to_check":"- Check the installed joi version with `npm ls joi`; affected versions are from `17.1.1` up to but not including `17.13.9`, and `18.3.1`.\n- Search the codebase for `email({ multiple: true })` or `email({multiple: true` to find validators that accept attacker-controlled input.\n- Check whether a `.max()` length limit runs before the email rule, and whether `abortEarly: false` is set.","fix":"- joi `17.x`: move to `17.13.9`\n- joi `18.x`: move to `18.3.1`","status":"open","published_at":"2026-10-29T19:17:19+00:00","first_seen_at":"2026-10-29T19:26:47+00:00","triaged_at":"2026-10-29T19:27:28+00:00","updated_at":"2026-10-29T19:27:28+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-10-29T19:27:28Z","model":"claude-haiku-5-5","output":{"fix":"- joi `17.x`: move to `17.13.9`\n- joi `18.x`: move to `18.3.1`","reach":"internet","title":"joi: email multiple option lets one long input block Node event loop","impact":"low","summary":"Joi's email validator with the multiple option uses a regular expression that runs in quadratic time on long whitespace runs. A single crafted request can block the Node.js event loop for seconds, stalling other work in the server.","audience":"developers","category":"package","nicknames":[],"who_cares":["node.js","joi","javascript","backend","api"],"confidence":0.8,"fix_status":"available","needs_auth":"unknown","worst_case":"one request blocks the Node.js event loop for seconds","analyst_note":"","how_to_check":"- Check the installed joi version with `npm ls joi`; affected versions are from `17.1.1` up to but not including `17.13.9`, and `18.3.1`.\n- Search the codebase for `email({ multiple: true })` or `email({multiple: true` to find validators that accept attacker-controlled input.\n- Check whether a `.max()` length limit runs before the email rule, and whether `abortEarly: false` is set.","plain_action":"","needs_analyst":false,"not_affected_if":["no-multiple-option","trusted-input-only","length-checked-first"],"who_is_affected":"Applications that call Joi.string().email({ multiple: true }) on attacker-controlled values. A length limit only protects the code if it runs first; with abortEarly: false the email rule can still run on an oversized value. Projects that do not use the multiple option, or validate only trusted input, are not exposed.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.000725,"input_tokens":4266,"output_tokens":596,"severity_before":"high"},"analyst_status":null,"analyst_note":null,"search":"'-118772':15A,18A '-2026':14A,17A '17.1.1':76C '17.13.9':78C,186C '18.3.1':80C,188C 'abortear':165C 'allow':167C 'api':19B 'appli':117C 'applic':126C 'attack':130C 'attacker-control':129C 'backend':20B 'behavior':116C 'block':9A,51B,149C 'caus':110C 'check':178C 'contain':107C 'control':131C 'craft':48B 'custom':124C 'cve':13A,16A 'data':71C 'default':120C 'descript':68C 'effect':139C 'email':2A,27B,83C,169C 'event':11A,54B,147C 'everi':99C,123C 'express':36B,91C 'fail':179C 'fals':166C 'fix':183C 'input':8A 'javascript':21B,74C 'joi':1A,22B,25B,64C 'joi.string':82C 'languag':69C 'lead':93C 'length':141C,177C 'let':5A 'limit':142C 'long':7A,43B,103C 'loop':12A,55B,148C 'max':159C 'maximum':176C 'maximum-length':175C 'multipl':3A,31B,84C,135C 'node':10A 'node.js':23B,53B,146C 'one':6A,153C 'option':4A,32B,136C 'packag':24B 'posit':100C 'prevent':155C 'prior':140C 'quadrat':40B,111C 'quantifi':95C 'regular':35B,90C 'request':49B,154C 'retri':97C 'rule':86C,160C,170C 'run':38B,45B,105C,172C 'schema':67C 'second':57B,151C 'separ':89C,109C,121C,125C 'server':63B 'singl':47B 'stall':58B 'string.prototype.split':114C 'suffici':163C 'time':41B 'true':85C 'use':33B,87C 'valid':28B,72C,128C 'valu':132C 'version':185C 'vulner':181C 'whitespac':44B,94C,104C 'whose':92C 'work':60B,112C,157C","nicknames":[],"mitigations":[],"who_affected":"Applications that call Joi.string().email({ multiple: true }) on attacker-controlled values. A length limit only protects the code if it runs first; with abortEarly: false the email rule can still run on an oversized value. Projects that do not use the multiple option, or validate only trusted input, are not exposed.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"first_public_at":"2026-10-29T19:17:19+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","cvss_by":"security-advisories@github.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-118772","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-118772","severity":null,"published_at":"2026-10-29T19:17:19+00:00","modified_at":"2026-10-29T19:17:19+00:00","first_seen_at":"2026-10-29T19:26:47+00:00","fetched_at":"2026-10-29T19:26:47+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}