GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GCVE-1988-2026-0230

Vulnerability from gna-1988 – Published: 2026-09-08 07:57 – Updated: 2026-09-09 10:07
VLAI
Title
CVE-2025-12758: Unicode Variation Selectors Bypass in 'validator' library (isLength)
Summary
Summary ======= A vulnerability was discovered in the popular JavaScript library 'validator'. The isLength() function incorrectly handles Unicode Variation Selectors (U+FE0E and U+FE0F). An attacker can inject thousands of these zero-width characters into a string, causing the library to report a much smaller perceived length than the actual byte size. This leads to validation bypasses, potential database truncation, and Denial of Service (DoS). Metadata ======== CVE ID: CVE-2025-12758 Vulnerability Type: Incomplete Filtering of Special Elements (CWE-792) Affected Package: validator (npm) Affected Versions: < 13.15.22 Fixed Version: 13.15.22 CVSS Score: 7.5 (High) - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H Description =========== The 'validator' library's isLength() method is widely used to enforce constraints on input data. However, the implementation failed to account for Unicode Variation Selectors. These are zero-width code points that modify the presentation of the preceding character (e.g., changing a text character into an emoji). Because these characters have zero width but occupy bytes in memory (UTF-16 surrogate pairs or single code points depending on the environment), an attacker can craft a payload that: 1. Appears to have a length of 1 (e.g., 'a' followed by 5000 variation selectors). 2. isLength() reports it as length 1 or 2 (depending on internal logic). 3. The actual memory/storage size is massive (e.g., 10,000+ bytes). Impact ====== - Denial of Service (DoS): Sending extremely large payloads that pass length checks can exhaust server memory or CPU during processing. - Data Truncation: Databases with strict byte limits (e.g., VARCHAR(255)) may truncate the string, potentially leading to data corruption or application logic errors. - Security Bypass: Bypassing UI or API limits intended to prevent large blobs of data. Proof of Concept (PoC) ====================== const validator = require('validator'); // 'a' followed by many Variation Selector-16 (\uFE0F) const payload = 'a' + '\uFE0F'.repeat(5000); console.log("Actual length (chars):", payload.length); // 5001 console.log("Validator isLength(payload, {max: 5}):", validator.isLength(payload, {max: 5})); // In vulnerable versions, this returns 'true' because selectors // were not properly counted or were ignored in a way that bypassed // the total length check. Fix === The issue was fixed in version 13.15.22 by implementing a surgical fix that correctly identifies and counts valid Unicode pairs and variation selectors, ensuring the reported length matches the actual data footprint more accurately. Timeline ======== - 2025-10-18: Vulnerability reported to maintainers by Karol Wrótniak. - 2025-11-27: CVE-2025-12758 published. - 2025-11-09: Fixed version 13.15.22 released. References ========== [1] https://www.thedroidsonroids.com/blog/when-zero-width-isnt-zero [2] https://nvd.nist.gov/vuln/detail/CVE-2025-12758 [3] https://github.com/validatorjs/validator.js/releases/tag/13.15.22 -- *Karol Wrótniak * Senior Android Developer */* [image: Logo] www.droidsonroids.com <https://www.thedroidsonroids.com/> Wrocław, ul. Sikorskiego 26, 53-659 Poland [image: Clutch Profile] <https://clutch.co/profile/droids-roids> [image: Dribbble Profile] <https://dribbble.com/DroidsOnRoids> [image: Behance Profile] <https://www.behance.net/droidsonroids> [image: Instagram Profile] <https://www.instagram.com/droidsonroidsmobile/> [image: Github Profile] <https://github.com/DroidsOnRoids> [image: X Profile] <https://twitter.com/droidsonroids> [image: Facebook Profile] <https://www.facebook.com/droidsonroids> [image: Linkedin Profile] <https://pl.linkedin.com/company/droids-on-roids?trk=public_profile_topcard-current-company> _______________________________________________ Sent through the Full Disclosure mailing list https://nmap.org/mailman/listinfo/fulldisclosure Web Archives & RSS: https://seclists.org/fulldisclosure/
Severity
No CVSS data available.
CWE
Impacted products
Vendor Product Version CPE status
Cve CVE-2025-12758 Unicode Variation Affected: unknown
guessed Create a notification for this product.
Relationships
analysis GCVE-1988-2026-0230 (this record)

{
  "containers": {
    "cna": {
      "affected": [
        {
          "product": "CVE-2025-12758 Unicode Variation",
          "vendor": "Cve",
          "versions": [
            {
              "status": "affected",
              "version": "unknown"
            }
          ]
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Karol Wr\u00f3tniak"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "Summary\n=======\nA vulnerability was discovered in the popular JavaScript library\n\u0027validator\u0027.\nThe isLength() function incorrectly handles Unicode Variation Selectors\n(U+FE0E and U+FE0F). An attacker can inject thousands of these zero-width\ncharacters into a string, causing the library to report a much smaller\nperceived length than the actual byte size. This leads to validation\nbypasses,\npotential database truncation, and Denial of Service (DoS).\n\nMetadata\n========\nCVE ID: CVE-2025-12758\nVulnerability Type: Incomplete Filtering of Special Elements (CWE-792)\nAffected Package: validator (npm)\nAffected Versions: \u003c 13.15.22\nFixed Version: 13.15.22\nCVSS Score: 7.5 (High) - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H\n\nDescription\n===========\nThe \u0027validator\u0027 library\u0027s isLength() method is widely used to enforce\nconstraints on input data. However, the implementation failed to account\nfor\nUnicode Variation Selectors. These are zero-width code points that modify\nthe\npresentation of the preceding character (e.g., changing a text character\ninto\nan emoji).\n\nBecause these characters have zero width but occupy bytes in memory (UTF-16\nsurrogate pairs or single code points depending on the environment), an\nattacker can craft a payload that:\n1. Appears to have a length of 1 (e.g., \u0027a\u0027 followed by 5000 variation\nselectors).\n2. isLength() reports it as length 1 or 2 (depending on internal logic).\n3. The actual memory/storage size is massive (e.g., 10,000+ bytes).\n\nImpact\n======\n- Denial of Service (DoS): Sending extremely large payloads that pass\nlength\n  checks can exhaust server memory or CPU during processing.\n- Data Truncation: Databases with strict byte limits (e.g., VARCHAR(255))\n  may truncate the string, potentially leading to data corruption or\n  application logic errors.\n- Security Bypass: Bypassing UI or API limits intended to prevent large\n  blobs of data.\n\nProof of Concept (PoC)\n======================\nconst validator = require(\u0027validator\u0027);\n\n// \u0027a\u0027 followed by many Variation Selector-16 (\\uFE0F)\nconst payload = \u0027a\u0027 + \u0027\\uFE0F\u0027.repeat(5000);\n\nconsole.log(\"Actual length (chars):\", payload.length); // 5001\nconsole.log(\"Validator isLength(payload, {max: 5}):\",\n            validator.isLength(payload, {max: 5}));\n\n// In vulnerable versions, this returns \u0027true\u0027 because selectors\n// were not properly counted or were ignored in a way that bypassed\n// the total length check.\n\nFix\n===\nThe issue was fixed in version 13.15.22 by implementing a surgical fix\nthat correctly identifies and counts valid Unicode pairs and variation\nselectors, ensuring the reported length matches the actual data footprint\nmore accurately.\n\nTimeline\n========\n- 2025-10-18: Vulnerability reported to maintainers by Karol Wr\u00f3tniak.\n- 2025-11-27: CVE-2025-12758 published.\n- 2025-11-09: Fixed version 13.15.22 released.\n\nReferences\n==========\n[1] https://www.thedroidsonroids.com/blog/when-zero-width-isnt-zero\n[2] https://nvd.nist.gov/vuln/detail/CVE-2025-12758\n[3] https://github.com/validatorjs/validator.js/releases/tag/13.15.22\n\n-- \n*Karol Wr\u00f3tniak *\nSenior Android Developer\n\n*/*\n[image: Logo]\n\nwww.droidsonroids.com \u003chttps://www.thedroidsonroids.com/\u003e\nWroc\u0142aw, ul. Sikorskiego 26, 53-659 Poland\n\n[image: Clutch Profile] \u003chttps://clutch.co/profile/droids-roids\u003e [image:\nDribbble Profile] \u003chttps://dribbble.com/DroidsOnRoids\u003e [image: Behance\nProfile] \u003chttps://www.behance.net/droidsonroids\u003e [image: Instagram Profile]\n\u003chttps://www.instagram.com/droidsonroidsmobile/\u003e [image: Github Profile]\n\u003chttps://github.com/DroidsOnRoids\u003e [image: X Profile]\n\u003chttps://twitter.com/droidsonroids\u003e [image: Facebook Profile]\n\u003chttps://www.facebook.com/droidsonroids\u003e [image: Linkedin Profile]\n\u003chttps://pl.linkedin.com/company/droids-on-roids?trk=public_profile_topcard-current-company\u003e\n_______________________________________________\nSent through the Full Disclosure mailing list\nhttps://nmap.org/mailman/listinfo/fulldisclosure\nWeb Archives \u0026 RSS: https://seclists.org/fulldisclosure/"
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-792",
              "description": "CWE-792",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-09-09T10:07:08Z",
        "orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
        "shortName": "VULNARCHIVE"
      },
      "references": [
        {
          "tags": [
            "technical-description",
            "exploit"
          ],
          "url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Jan/27"
        },
        {
          "tags": [
            "technical-description"
          ],
          "url": "https://seclists.org/fulldisclosure/2026/Jan/27"
        },
        {
          "url": "https://clutch.co/profile/droids-roids"
        },
        {
          "url": "https://dribbble.com/DroidsOnRoids"
        },
        {
          "url": "https://github.com/DroidsOnRoids"
        },
        {
          "url": "https://github.com/validatorjs/validator.js/releases/tag/13.15.22"
        },
        {
          "url": "https://nmap.org/mailman/listinfo/fulldisclosure"
        },
        {
          "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-12758"
        },
        {
          "url": "https://pl.linkedin.com/company/droids-on-roids?trk=public_profile_topcard-current-company"
        },
        {
          "url": "https://seclists.org/fulldisclosure/"
        },
        {
          "url": "https://twitter.com/droidsonroids"
        },
        {
          "url": "https://www.behance.net/droidsonroids"
        },
        {
          "url": "https://www.facebook.com/droidsonroids"
        },
        {
          "url": "https://www.instagram.com/droidsonroidsmobile/"
        },
        {
          "url": "https://www.thedroidsonroids.com/"
        },
        {
          "url": "https://www.thedroidsonroids.com/blog/when-zero-width-isnt-zero"
        }
      ],
      "source": {
        "defect": [
          "https://seclists.org/fulldisclosure/2026/Jan/27"
        ],
        "discovery": "EXTERNAL"
      },
      "title": "CVE-2025-12758: Unicode Variation Selectors Bypass in \u0027validator\u0027 library (isLength)",
      "x_gcve": [
        {
          "recordType": "analysis",
          "relationships": [
            {
              "destId": "CVE-2025-12758",
              "type": "related"
            }
          ],
          "vulnId": "GCVE-1988-2026-0230",
          "x_vulnarchive": {
            "archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Jan/27",
            "automated": true,
            "contentSha256": "3f811160419685e23714b714c4bc76a905be3ad2cebf526de9f1b9e8a9f41764",
            "evidenceScore": 11,
            "messageId": "",
            "originalUrl": "https://seclists.org/fulldisclosure/2026/Jan/27",
            "policy": "vulnarchive-1",
            "sourceFormat": "text/html",
            "sourcePublishedAt": "2026-01-28T18:24:40Z"
          }
        },
        {
          "recordType": "advisory",
          "vulnId": "gcve-1988-2026-0230"
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
    "assignerShortName": "VULNARCHIVE",
    "datePublished": "2026-09-08T07:57:43Z",
    "dateUpdated": "2026-09-09T10:07:08Z",
    "state": "PUBLISHED",
    "vulnId": "GCVE-1988-2026-0230"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…