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
Assigner
VULNARCHIVE GNA GNA-1988
GNA scorecard E 38/100 over 445 records in the last 180 days details
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…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…