Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessSubmit 9-byte \verb payload via HTTP or API
-
DeliveryParser processes \verb command with multibyte delimiter
-
ExploitByte-index slice at parser.rs:910 hits non-char boundary
-
ExecutionRust panic triggered (CWE-248)
-
Persistpanic=abort calls abort()
-
ImpactEntire server process terminates
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A10:2025 - Mishandling of Exceptional Conditions
ASVS 5.0
V16 - Security Logging and Error Handling Exception handling completeness
|
| Exploitation Conditions | No special conditions - remote unauthenticated exploitation against any deployment of ratex-parser (versions < 0.1.11) that passes unsanitized user input to ratex_parser::parse(). The sole prerequisite is that the attacker-controlled string reaches the parse() entrypoint containing a \verb command followed by a multibyte UTF-8 character (any character with a Unicode code point above U+007F whose UTF-8 encoding exceeds one byte). Exploitation is deterministic and requires no brute-forcing or timing. Limiting factors: the vulnerability only affects the availability of the process (no data exfiltration or integrity impact); exploitation is constrained to deployments where user-supplied LaTeX reaches the parser without prior sanitization; WASM deployments may scope the abort to the WASM module rather than the host process depending on the runtime's abort handler; and the affected product has a narrow deployment footprint compared to widely deployed libraries. |
| Impact | The CVSS 4.0 score of 8.7 (AV:N/AC:L/AT:N/PR:N/UI:N/VA:H) accurately reflects the practical threat: the attack requires no authentication, no special network position, and no user interaction, and the trigger is a deterministic 9-byte payload. EPSS data was not provided in the source intelligence, so exploitation probability cannot be quantified; however, a publicly available proof-of-concept lowers the skill threshold for exploitation to near zero. This vulnerability is not listed in the CISA KEV catalog at the time of analysis, indicating no confirmed widespread active exploitation. The availability impact is severe because panic = "abort" eliminates Rust's usual thread-isolation safety net - a crash is process-wide, meaning a single malicious formula can deny service to all concurrent users. The confidentiality and integrity scores are both zero, which is accurate; this is a pure DoS with no data-exfiltration or tampering vector. The primary limiting factor on real-world risk is the relatively narrow deployment footprint of ratex-parser itself - this is not a ubiquitous component like OpenSSL or Log4j. The fix (0.1.11) is available and the remediation is low-risk, so the operational priority is straightforward: patch promptly for any internet-facing service rendering untrusted LaTeX, and consider catch_unwind at FFI or WASM boundaries as a defense-in-depth measure. |
| Exploit ScenarioDerived | A publicly available proof-of-concept confirms the attack: an attacker sends the 9-byte string \verbéxé (raw bytes: 5c 76 65 72 62 c3 a9 78 c3 a9) to any HTTP endpoint or API that passes user-supplied input to ratex_parser::parse(). The parser's byte-slice operation immediately panics, and because the release binary is compiled with panic = "abort", the entire server process terminates with exit code 134, denying service to all current and queued requests. No prior knowledge of the target, no authentication, and no special network access are required. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv2 – Aug 21, 2026
Process-aborting denial of service in ratex-parser (Rust crate) allows any remote unauthenticated attacker to crash the entire hosting process by submitting a 9-byte LaTeX string containing a multibyte UTF-8 delimiter in a \verb command. The parser at parser.rs:910 slices the verbatim argument using byte indices rather than character indices; when the delimiter is a multibyte character such as é (U+00E9, two bytes), byte index 1 falls inside the character boundary, triggering a Rust panic that - due to panic = "abort" in the release profile - terminates the whole process rather than unwinding a single thread. A publicly available proof-of-concept demonstrates reliable reproduction, and vendor-released patch version 0.1.11 is available.
Earlier versions of this analysis (1)
Denial of service in RaTeX, a Rust LaTeX-rendering library (crate ratex-parser), lets remote attackers crash any service that parses untrusted LaTeX by submitting a 9-byte \verb command whose delimiter is a multibyte UTF-8 character (e.g. \verbéxé). The parser slices the verbatim argument using byte indices rather than character boundaries, so index 1 lands inside the é character and Rust panics; because the release profile sets panic = "abort", the panic terminates the entire process, not just one request. Publicly available exploit code exists (a one-line PoC in the GHSA advisory); no active exploitation is reported.
RemediationAI
Vendor-released patch: 0.1.11. Upgrade ratex-parser to version 0.1.11 or later, which corrects the byte-index slicing in parse_symbol_inner to use character-boundary-aware indexing (chars().collect() and char-based slice operations). The advisory and patch are referenced at https://github.com/erweixin/RaTeX/security/advisories/GHSA-4hgp-59h5-gvrj. As an immediate compensating control prior to patching, services can apply input validation at the application layer to reject or sanitize any LaTeX input containing non-ASCII characters before passing it to ratex_parser::parse(); this limits exposure but may break legitimate internationalized formulas. A further defensive measure recommended by the advisory - regardless of patching - is wrapping parsing calls in std::panic::catch_unwind at all FFI and WASM boundaries, which would convert an abort into a recoverable error; however, this does not address the root cause and cannot prevent the abort in release builds where panic = "abort" overrides unwind semantics. Changing panic = "abort" to panic = "unwind" in the release profile would restore thread-level isolation but has binary-size and performance trade-offs and is a build-configuration change that requires recompilation.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in cargo, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
RaTeX is a Rust-based LaTeX parser exposing a public entrypoint ratex_parser::parse(&str). The vulnerability resides in parse_symbol_inner within crates/ratex-parser/src/parser.rs at line 910, classified as CWE-248 (Uncaught Exception). The root cause is a byte-index string slice operation arg[1..arg.len() - 1] applied to a UTF-8 Rust &str. In Rust, string byte-index slicing panics at runtime if the requested index does not fall on a valid UTF-8 character boundary. The delimiter character é (U+00E9) encodes as two bytes (0xC3 0xA9), so byte index 1 falls inside the character, not at a boundary, triggering the panic. Critically, RaTeX's Cargo.toml (line 48) sets panic = "abort" in the release profile, meaning the panic does not unwind the thread stack but immediately calls abort(), killing the entire process. The lexer (lexer.rs lex_verb) already handles this correctly using character-aware semantics, making the inconsistency a localized parser bug. The affected package is pkg:rust/ratex-parser in all versions prior to 0.1.11.
Know when the next one hits your stack
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Network-reachable with no authentication, interaction, or special conditions; sole impact is high availability loss via process abort with no scope change beyond the vulnerable component.
Primary rating from Vendor (https://github.com/erweixin/RaTeX).
CVSS VectorVendor: https://github.com/erweixin/RaTeX
Lifecycle Timeline
2DescriptionCVE.org
Summary
The public parser entrypoint ratex_parser::parse(&str) panics on the 9-byte input \verbéxé (i.e. \verb followed by the non-ASCII delimiter é). When handling a \verb command, the parser slices the verbatim argument with byte indices (arg[1..arg.len() - 1]); if the delimiter character is multibyte UTF-8, index 1 lands inside that character and Rust panics with *“byte index 1 is not a char boundary”*. Because RaTeX’s release profile sets panic = "abort" (Cargo.toml:48), the panic aborts the entire process - not just the current request/thread - making this a hard denial of service for any service that renders untrusted LaTeX.
Details
Affected code
crates/ratex-parser/src/parser.rs, parse_symbol_inner:
if let Some(stripped) = text.strip_prefix("\\verb") { // parser.rs:901
self.consume();
let arg = stripped.to_string(); // e.g. "éxé"
let star = arg.starts_with('*');
let arg = if star { &arg[1..] } else { &arg }; // parser.rs:905 (also byte-sliced)
if arg.len() < 2 { // byte length
return Err(ParseError::new("\\verb assertion failed", Some(&nucleus)));
}
let body = arg[1..arg.len() - 1].to_string(); // parser.rs:910 <-- PANIC on multibyte delimiter
...
}For input \verbéxé: arg = "éxé", where é = U+00E9 (bytes C3 A9). arg.len() is the byte length (5), the < 2 guard passes, and arg[1..4] starts at byte index 1 - inside the first é (bytes 0..2) - so the slice panics. The lexer groups \verb<delim>…<delim> correctly with char semantics (lexer.rs lex_verb); only the parser mishandles it.
PoC
<img width="1109" height="205" alt="image" src="https://github.com/user-attachments/assets/cd4bc6ae-23dd-458f-826c-6ce4e85c7005" />
$ printf '\\verb\xc3\xa9x\xc3\xa9\n' | ./target/release/parse
thread 'main' panicked at crates/ratex-parser/src/parser.rs:910:27:
start byte index 1 is not a char boundary; it is inside 'é' (bytes 0..2 of string)
Aborted (core dumped)
# exit 134 - panic=abort kills the whole processImpact
Any application that renders untrusted LaTeX through RaTeX (web “render this math” endpoint, WASM in-browser use, the FFI embedded in another app) can be crashed by a tiny string. With panic = "abort" in release builds, the crash takes down the whole process / server, so a single malicious formula causes a full-service DoS (and, in batch pipelines, drops all queued work).
Remediation
Slice by character boundaries instead of byte indices, mirroring the UTF-8-correct logic the lexer already uses. For example:
let chars: Vec<char> = arg.chars().collect();
if chars.len() < 2 { return Err(ParseError::new("\\verb assertion failed", Some(&nucleus))); }
let body: String = chars[1..chars.len() - 1].iter().collect();(Apply the same char-aware handling to the * strip at parser.rs:905.) More broadly, consider not using panic = "abort" for builds embedded in long-running services, and/or wrapping parsing in catch_unwind at the FFI/WASM boundary - but the byte-slice fix is the direct correction.
Executive ViewAI
The ratex-parser Rust library contains a high-severity denial-of-service vulnerability (CVSS 8.7) allowing unauthenticated remote attackers to crash entire application processes with a single 9-byte request; publicly available exploit code exists. Organizations using ratex-parser in production must immediately patch to prevent service outages and customer impact.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.
EUVD-2026-64179
GHSA-4hgp-59h5-gvrj
NVD
CVE.org
EPSS
Exploit-DB