Aug 27, 2026·6 min read·20 visits
Unsanitized input in options.fileName allows attackers to perform directory traversal and write arbitrary files anywhere on the host filesystem that the Node.js process can write to, which can lead to remote code execution.
A path traversal and arbitrary file write vulnerability exists in the libreoffice-convert Node.js package in all versions prior to 1.8.2. The convertWithOptions function fails to validate or sanitize the caller-controlled options.fileName parameter, allowing directory traversal sequences to write files outside the temporary directory.
The Node.js package libreoffice-convert provides an interface to convert office documents to various formats using the LibreOffice command-line utility. Applications processing user-provided documents often expose configuration options to tailor the conversion output, such as custom output filenames. This architecture exposes a significant attack surface if input validation is delegated entirely to the underlying libraries without structural sanitization.
In versions prior to 1.8.2, the library introduces an arbitrary file write vulnerability categorized under CWE-22 (Improper Limitation of a Pathname to a Restricted Directory). The core conversion routine accepts a caller-defined filename parameter designed to designate the source file name within a temporary directory. Because this value is used in path construction without validation, it can contain relative directory traversal components.
This vulnerability is particularly critical because of its direct escalation potential. An attacker able to write arbitrary files on the host filesystem can target critical directories to modify system execution flows. Depending on the hosting architecture, this execution control can result in complete system compromise or lateral movement within the hosting network infrastructure.
The vulnerability resides within the file initialization phase of the conversion routine in index.js. When the convertWithOptions function is called, it initializes a sandbox directory under /tmp to isolate the temporary files generated during LibreOffice operations. The generation of file paths inside this sandbox relies on the standard Node.js path module, specifically path.join.
The application defines the output filename dynamically using the caller-supplied options payload. The source code defines the variable assignment as const fileName = (options || {}).fileName || 'source'. This parameter is subsequently passed directly to path.join(tempDir.name, fileName). The path.join function is designed to concatenate path segments and resolve the resulting path, including processing relative traversal sequences.
When options.fileName contains sequences such as ../../, the resolver processes these segments relative to the root of the temporary sandbox. Since there are no checks preventing the path from resolving to a parent directory, the destination path escapes the sandbox boundaries. The application then executes fs.writeFileSync(filePath, document) using the resolved path, writing the user-supplied document buffer to an unintended filesystem location.
The vulnerability was addressed in version 1.8.2 by introducing a standard path isolation mechanism using path.basename(). Below is the technical comparison of the affected code path versus the patched implementation.
Prior to the patch, the file creation logic resolved the destination path as follows:
// Vulnerable Code Path in index.js
const fileName = (options || {}).fileName || 'source';
// ...
const tempDir = tmp.dirSync({prefix: 'libreofficeConvert_', unsafeCleanup: true, ...tmpOptions});
const filePath = path.join(tempDir.name, fileName);
// ...
fs.writeFileSync(filePath, document);The corresponding patch introduces the extraction of the base terminal portion of the path parameter:
// Patched Code Path in index.js (Version 1.8.2)
const fileName = path.basename((options || {}).fileName || 'source');
// ...
const tempDir = tmp.dirSync({prefix: 'libreofficeConvert_', unsafeCleanup: true, ...tmpOptions});
const filePath = path.join(tempDir.name, fileName);
// ...
fs.writeFileSync(filePath, document);By enclosing the parameter in path.basename(), the application discards all preceding directory elements, including relative structures and separators. If an attacker submits a path such as ../../../../etc/shadow, path.basename resolves this string purely to shadow. Consequently, the file is forced to resolve exclusively inside the designated /tmp/libreofficeConvert_XXXXXX directory, preventing arbitrary traversal.
Security teams should observe that on POSIX systems, path.basename does not interpret Windows-style backslashes (\\) as directory separators, treating them instead as valid filename characters. While this blocks traversal outside the sandbox on POSIX containers, submitting a filename with backslashes on a POSIX system creates a file with backslashes in its name within the temporary directory. Developers should ensure that downstream processing does not interpret these characters in a way that introduces secondary execution risks.
Exploitation of this vulnerability requires that an application exposes the document conversion endpoint to client-controlled input. The attacker must be capable of structuring the request payload to contain a custom options object with the fileName parameter and a malicious document buffer.
The target application must invoke convertWithOptions using this client-supplied config. The prerequisite for full remote code execution is that the Node.js process is executing with privileges sufficient to write to sensitive system locations. For instance, if the process runs within a container as root, the attacker can target cron configuration files, SSH structures, or application startup files.
A typical exploit structure targets known administrative files. An attacker could construct an options payload referencing a target configuration file such as /etc/cron.d/scheduler or .ssh/authorized_keys. By submitting the corresponding file contents in the document parameter, the write operation overwrites or establishes persistence on the victim system.
The impact of CVE-2026-54732 is assessed as Medium (CVSS Base Score 6.5) due to the constraints of the execution context. While the vulnerability allows full integrity loss (Integrity: High), it does not directly facilitate confidentiality exposure or denial of service natively (Confidentiality: None, Availability: None).
In real-world deployments, however, this vulnerability frequently acts as an entry vector for high-severity compromise. If the runtime user possesses write permissions to system directories, an attacker can modify files like /etc/cron.d/ to execute arbitrary system commands within a short window. In situations where the server hosts a web application root with write permissions, the attacker can write a web shell directly into the document root to gain shell access.
If the application operates within a tightly sandboxed environment or under a non-privileged user account, the write scope is limited. The integrity impact would then be restricted to files owned by the application user, limiting the potential for system-wide compromise.
The primary remediation for this vulnerability is to upgrade the libreoffice-convert dependency to version 1.8.2 or above. This version implements input parsing that safely isolates filenames inside the target directory.
In legacy setups where upgrading is not immediately possible, application-level input sanitation must be enforced before invoking the library. This should involve strip-filtering directory separators from incoming parameters. A robust utility should convert all platform-specific separators (such as backslashes) to forward slashes and extract the base filename manually.
function safeExtractName(dirtyName) {
if (typeof dirtyName !== 'string') return 'source';
const clean = dirtyName.replace(/\\/g, '/');
return path.basename(clean);
}Beyond code-level fixes, systemic containment is critical. Applications executing conversion engines should be restricted to minimal permissions. Operating the Node.js service under a distinct, non-privileged system user prevents file modification in system directories even if path traversal is successfully exploited.
| Product | Affected Versions | Fixed Version |
|---|---|---|
libreoffice-convert elwerene | < 1.8.2 | 1.8.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Network |
| CVSS Score | 6.5 |
| Integrity Impact | High |
| Exploit Status | none |
| KEV Status | Not Listed |
The software uses external input to construct a pathname that should be within a restricted directory, but it does not properly sanitize the input, allowing path traversal components to resolve outside the restricted directory.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.