Corey Farley

CVE-2026-27897: Path Traversal & Arbitrary File Write in Vociferous

CVE-2026-27897: Path Traversal & Arbitrary File Write in Vociferous

A technical breakdown of CVE-2026-27897, a high-severity path traversal and arbitrary file write vulnerability I discovered during a security audit of the Vociferous application.

I recently did a security audit for a friend’s project, Vociferous, and ended up discovering a path traversal vulnerability that allowed for unauthenticated arbitrary file writes. The vulnerability was officially assigned CVE-2026-27897 .

Here is a breakdown of the application, how the exploit works, and the steps required to remediate it.


What is Vociferous?

Vociferous is a cross-platform, offline speech-to-text application that utilizes local AI refinement. It features a backend API to handle system-level operations and file exports, which is where the vulnerability was identified.

The Vulnerability (CWE-22 & CWE-306)

Vociferous versions prior to 4.4.2 are vulnerable to CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) and CWE-306 (Missing Authentication for Critical Function).

The core of the issue exists in the export_file route within src/api/system.py. The application’s internal API accepts a JSON payload containing a filename and content. However, the API does not validate or sanitize the filename string before processing it.

Because the API lacks authentication and features an overly permissive CORS configuration (allow_origins=["*"] or allowing localhost), it allows an external attacker to bypass the native UI entirely. By passing directory traversal sequences (like ../../), an attacker can manipulate the application into writing arbitrary data to any location on the disk, restricted only by the permissions of the user running the application.

CVSS Score Breakdown

The vulnerability was recognized by NIST as a 7.1 HIGH:

CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H

  • Attack Vector (Local - AV:L): The attacker needs local access to the system or must execute the attack via a local vector (like CSRF via a browser running on the same machine).
  • Attack Complexity (Low - AC:L): The exploit is trivial to execute and does not rely on race conditions or complex bypassing.
  • Privileges Required (None - PR:N): The attacker does not need to be authenticated to the Vociferous application or the API.
  • User Interaction (Required - UI:R): The exploit relies on the user clicking “Save” on the native GTK dialog prompt that the application generates.
  • Scope (Unchanged - S:U): The vulnerability affects resources managed by the same security authority.
  • Confidentiality (None - C:N): The vulnerability is an arbitrary file write, not a read, so no data is exposed.
  • Integrity (High - I:H): An attacker can completely overwrite critical system or user files.
  • Availability (High - A:H): Overwriting critical configuration files or system scripts can render the user’s environment or the application completely unusable.

Official NVD post: https://nvd.nist.gov/vuln/detail/CVE-2026-27897


Impact Scenario: Cross-User Impact

In a standalone, single-user environment, this is bad, but in a shared system environment (like a corporate jump box or shared development server), this vulnerability leads to severe cross-user impact which is where most of my focus for this vulnerability was put.

Imagine Bob and Alice are both logged into the same shared server:

  1. Bob is running Vociferous to help with his note taking, reporting, etc.
  2. Alice (a low-privileged user or an attacker) cannot access Bob’s files directly, due to OS-level permissions.
  3. But because Vociferous binds to a local port without authentication, Alice can simply send a POST request to localhost:18900/api/export and specify any payload or location (within Bob’s privileges) she desires.
  4. In conclusion, Alice uses Bob’s running application instance to perform an arbitrary file write as Bob.

This allows Alice to drop malicious scripts into Bob’s directories, overwrite Bob’s configuration files, or even replace Bob authorized_keys file to gain permanent, unauthorized SSH access to Bob’s account.


Proof of Concept (PoC)

To exploit this, Vociferous needs to be running under a different user account than the attacker (e.g., running as root for maximum impact, though a standard user works as well).

The attacker simply crafts a POST request to the local API port, injecting directory traversal sequences into the filename parameter:

└─$ curl -X POST http://localhost:18900/api/export \
 -H "Content-Type: application/json" \
 -d '{"content": "test", "filename": "../../../../../root/test.txt"}'

This triggers the native file manager dialog on the victim’s screen. Once the victim clicks “Save”, the application writes the file outside of the intended export directory. We can verify the file was successfully written to the /root directory:

└─$ sudo ls -l /root
total 8
-rw-r--r-- 1 root root 4 Feb 21 01:53 test.txt

Remediation & Mitigation

To effectively patch this, a multi-layered security approach is required:

  • Input Sanitization: Wrap the incoming filename parameter in os.path.basename() before processing. This completely strips all path information and traversal sequences (like ../), forcing the file to stay safely inside the designated export directory.
  • API Authentication: Implement a Bearer Token or API Key generated at runtime. The frontend should include this token in all headers, and the backend should reject any traffic lacking it, neutralizing CSRF attacks.
  • Path Anchoring and Validation: Before executing a disk write, the backend must resolve the final path to its absolute form and verify that it strictly starts with the expected base directory (e.g., ~/Vociferous/Exports/).
  • Restrict CORS Policy: The CORSConfig should be explicitly refined to only allow trusted, specific origins, entirely avoiding the use of wildcards (*).

(Note: The developer successfully implemented path stripping using Path(…).name to neutralize the traversal sequences, resolving the vulnerability in version 4.4.2).