VYPR
High severityNVD Advisory· Published Jun 1, 2022· Updated Sep 16, 2024

Exponential ReDoS in devcert

CVE-2022-1929

Description

An exponential ReDoS vulnerability in the devcert npm package allows denial of service via crafted domain input to the certificateFor method.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

An exponential ReDoS vulnerability in the devcert npm package allows denial of service via crafted domain input to the certificateFor method.

Vulnerability

The devcert npm package (versions up to and including 1.2.0) contains an exponential ReDoS vulnerability in the VALID_DOMAIN regular expression used to validate domain names in the certificateFor method [1][2][4]. An attacker can supply a specially crafted string that causes the regex to exhibit exponential backtracking, leading to CPU exhaustion. The vulnerable regex was replaced in commit b0763215 with the is-valid-domain library [3].

Exploitation

An attacker needs to be able to supply arbitrary input to the certificateFor method, which may occur if an application passes user-controlled domain names to devcert. The attacker provides a string such as '0' + '000'.repeat(i) + '\\x00' to trigger exponential backtracking [4]. No authentication or special privileges are required beyond the ability to influence the domain argument.

Impact

Successful exploitation results in a denial of service (DoS) condition, where the Node.js process becomes unresponsive due to CPU exhaustion. The impact is limited to availability; no data confidentiality or integrity is compromised [2][4].

Mitigation

The vulnerability is fixed in devcert version 1.2.1, released on or around May 30, 2022 [3][4]. Users should upgrade to version 1.2.1 or later. No workarounds are documented; the fix replaces the vulnerable regex with the is-valid-domain library [3]. The CVE is not listed in CISA's Known Exploited Vulnerabilities catalog as of the publication date.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
devcertnpm
< 1.2.11.2.1

Affected products

2
  • ghsa-coords
    Range: < 1.2.1
  • devcert/devcertv5
    Range: unspecified

Patches

1
b0763215f668

switch from vulnerable VALID_DOMAIN regex to is-valid-domain lib (#79)

https://github.com/davewasmer/devcertJames ZetlenMay 3, 2022via ghsa
4 files changed · +35 11
  • package.json+2 2 modified
    @@ -45,13 +45,13 @@
         "eol": "^0.9.1",
         "get-port": "^3.2.0",
         "glob": "^7.1.2",
    +    "is-valid-domain": "^0.1.6",
         "lodash": "^4.17.4",
         "mkdirp": "^0.5.1",
         "password-prompt": "^1.0.4",
         "rimraf": "^2.6.2",
         "sudo-prompt": "^8.2.0",
         "tmp": "^0.0.33",
         "tslib": "^1.10.0"
    -  },
    -  "optionalDependencies": {}
    +  }
     }
    
  • package-lock.json+31 0 modified
    @@ -5,6 +5,7 @@
       "requires": true,
       "packages": {
         "": {
    +      "name": "devcert",
           "version": "1.2.0",
           "license": "MIT",
           "dependencies": {
    @@ -23,6 +24,7 @@
             "eol": "^0.9.1",
             "get-port": "^3.2.0",
             "glob": "^7.1.2",
    +        "is-valid-domain": "^0.1.6",
             "lodash": "^4.17.4",
             "mkdirp": "^0.5.1",
             "password-prompt": "^1.0.4",
    @@ -1825,6 +1827,14 @@
           "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
           "dev": true
         },
    +    "node_modules/is-valid-domain": {
    +      "version": "0.1.6",
    +      "resolved": "https://registry.npmjs.org/is-valid-domain/-/is-valid-domain-0.1.6.tgz",
    +      "integrity": "sha512-ZKtq737eFkZr71At8NxOFcP9O1K89gW3DkdrGMpp1upr/ueWjj+Weh4l9AI4rN0Gt8W2M1w7jrG2b/Yv83Ljpg==",
    +      "dependencies": {
    +        "punycode": "^2.1.1"
    +      }
    +    },
         "node_modules/isarray": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
    @@ -2404,6 +2414,14 @@
           "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
           "dev": true
         },
    +    "node_modules/punycode": {
    +      "version": "2.1.1",
    +      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
    +      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
    +      "engines": {
    +        "node": ">=6"
    +      }
    +    },
         "node_modules/q": {
           "version": "1.5.1",
           "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
    @@ -4637,6 +4655,14 @@
           "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
           "dev": true
         },
    +    "is-valid-domain": {
    +      "version": "0.1.6",
    +      "resolved": "https://registry.npmjs.org/is-valid-domain/-/is-valid-domain-0.1.6.tgz",
    +      "integrity": "sha512-ZKtq737eFkZr71At8NxOFcP9O1K89gW3DkdrGMpp1upr/ueWjj+Weh4l9AI4rN0Gt8W2M1w7jrG2b/Yv83Ljpg==",
    +      "requires": {
    +        "punycode": "^2.1.1"
    +      }
    +    },
         "isarray": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
    @@ -5097,6 +5123,11 @@
           "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
           "dev": true
         },
    +    "punycode": {
    +      "version": "2.1.1",
    +      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
    +      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
    +    },
         "q": {
           "version": "1.5.1",
           "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
    
  • src/constants.ts+0 3 modified
    @@ -6,9 +6,6 @@ import applicationConfigPath = require('application-config-path');
     import eol from 'eol';
     import {mktmp, numericHash} from './utils';
     
    -export const VALID_IP = /(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}/;
    -export const VALID_DOMAIN = /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.?)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$/i;
    -
     // Platform shortcuts
     export const isMac = process.platform === 'darwin';
     export const isLinux = process.platform === 'linux';
    
  • src/index.ts+2 6 modified
    @@ -11,13 +11,12 @@ import {
       domainsDir,
       rootCAKeyPath,
       rootCACertPath,
    -  VALID_DOMAIN,
    -  VALID_IP
     } from './constants';
     import currentPlatform from './platforms';
     import installCertificateAuthority, { ensureCACertReadable, uninstall } from './certificate-authority';
     import generateDomainCertificate from './certificates';
     import UI, { UserInterface } from './user-interface';
    +import isValidDomain from 'is-valid-domain';
     export { uninstall };
     
     const debug = createDebug('devcert');
    @@ -69,11 +68,8 @@ type IReturnData<O extends Options = {}> = (IDomainData) & (IReturnCa<O>) & (IRe
      */
     export async function certificateFor<O extends Options>(requestedDomains: string | string[], options: O = {} as O): Promise<IReturnData<O>> {
       const domains = Array.isArray(requestedDomains) ? requestedDomains : [requestedDomains];
    -  if (domains.some((d) => VALID_IP.test(d))) {
    -    throw new Error('IP addresses are not supported currently');
    -  }
       domains.forEach((domain) => {
    -    if (!VALID_DOMAIN.test(domain)) {
    +    if (!isValidDomain(domain, { subdomain: false, wildcard: false, allowUnicode: true, topLevel: false })) {
           throw new Error(`"${domain}" is not a valid domain name.`);
         }
       });
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.