// threat brief

nodejs-whisper command injection: a crafted audio file name can run system commands on the server

CVSS
9.3 CRITICAL
CISA KEV
Not listed
Weakness
CWE-78
Topics
Web apps

PlainCVE Team · Published 2026-10-15 · AI-assisted · Press brief ↓

AI review 2026-10-15 (not human-reviewed)Command tests: none yetReproduced: not yetVerification record ↓

nodejs-whisper 0.3.1 and earlier pass the audio file path to a shell, so a crafted file name can run OS commands; no fixed release is confirmed.

Who is affectedApplications using the npm package nodejs-whisper up to and including 0.3.1 that pass a user-influenced file name (for example, an upload saved under its original name) to nodewhisper() for transcription.
What happensIf those conditions hold, an attacker can run arbitrary system commands on the server with the Node.js process's privileges, and, according to the researcher, the command runs before transcription even starts.
What to do nowNo fixed version is confirmed. Don't pass user-influenced file names to nodewhisper(); save uploads under server-generated names, and watch whether PR #259 is merged and released.
Affected versionsAll versions up to and including 0.3.1; the researcher confirmed it on 0.3.0
Fixed versionsUnconfirmed: no fixed release is named in the available sources
Timeline
  • First public 2026-06-23

Blue team playbook

Check, fix / mitigate, respond, harden. Matching the affected versions does not mean you were compromised, and a check that finds nothing does not prove you are safe; each item says what it can and cannot show. Tagged steps point to where the attack flow below can be stopped.

DETECTCheckAm I affected? Any signs of compromise?
  1. 01Check whether your project uses nodejs-whisper and which version

    Run this in a terminal at your own project's root (the folder with package.json); it only reads your local dependency tree and changes nothing. Every version up to and including 0.3.1 is in the affected range. Check both direct and indirect dependencies; add --all to see the full dependency tree.

    Read-only check
    npm ls nodejs-whisper
  2. 02Check where file names come from

    Run this in a terminal at your own project's root; it only searches your local source code and changes no files. Find every call to nodewhisper() and check whether the path contains anything a user can influence, such as an upload's original file name. The researcher calls this the realistic exposure.

    Read-only check
    grep -rn "nodewhisper(" --include='*.js' --include='*.ts' --include='*.mjs' --include='*.cjs' --exclude-dir=node_modules .
MITIGATEFix / mitigatePatch; block it if you cannot patch yet
  1. 01Store uploads under server-generated names

    No fixed release is confirmed. If the path given to nodewhisper() is fully chosen by the server, the attacker loses control of the file name. This is PlainCVE's suggestion based on the exposure the researcher describes.

  2. 02Track whether PR #259 is merged and released

    PR #259 proposes running ffmpeg without a shell (that page contains attack code, so we don't link it), but the sources don't show whether it was merged or released. The command below works in any terminal with npm installed; you don't need to be in a project folder. It only queries the version list from the public npm registry and changes nothing. A version number alone doesn't show whether a release includes this fix, so when a new version appears, check its release notes or source code to confirm it includes the change before upgrading.

    Read-only check
    npm view nodejs-whisper versions
RESPONDRespondIf you find signs of compromise
  1. 01If you suspect exploitation, treat the host as compromised

    Injected commands run with the Node.js process's privileges, so any keys and credentials that process can read should be treated as possibly exposed and rotated. This is PlainCVE's suggestion; no source reports exploitation in the wild.

HARDENHardenPrevent the next one
  1. 01Don't go through a shell when calling external programs

    Use the PR #259 approach in your own code too: call programs with an argument array so file names are always just data.

  2. 02Run the transcription service with least privilege

    A separate account or container with no unnecessary secrets limits what a command injection can do (PlainCVE suggestion).

Full remediation steps and notes

There is no confirmed fixed version, and no maintainer advisory appears in the sources we reviewed. Suggested order (PlainCVE’s summary):

  1. Run npm ls nodejs-whisper to find where it’s used, including indirect dependencies.
  2. Take file names out of users’ hands right away: store uploads under a server-generated name and keep the original name only in your database for display. This doesn’t need to wait for an upstream fix.
  3. The third-party aggregator OffSeq also suggests not putting untrusted input into paths passed to convertToWavType() until a fix exists, and validating or sanitizing input. Note this is not the maintainer’s advice, and character filtering is easy to get wrong; renaming is more reliable than filtering.
  4. When a new version is released, confirm it includes the PR #259 change (running ffmpeg without a shell) before upgrading.

Attack flow

Read left to right: this is the order the attack happens in. A blue shield means the step can be stopped; the earlier, the better. Click an icon for details.

Read top to bottom: this is the order the attack happens in. A blue shield means the step can be stopped; the earlier, the better. Tap an icon for details.

nodejs-whisper command injection: a crafted audio file name can run system commands on the server: 1. Uploads an audio file with a specially crafted name → 2. The application passes that file path to nodewhisper() → 3. convertToWavType() pastes the path into an ffmpeg command string → 4. The shell runs part of the file name as a commandCVE-2026-110644 · nodejs-whisper command injection: a crafted audio file name can runsystem commands on the serverAttackerYour systemUploads an audio file with a specially crafted name — This only matters if the application keeps the user-supplied original file name. 1Uploads an audiofile with aspecially craftednameThe application passes that file path to nodewhisper() — nodewhisper(filePath, options) is the package's public API; the package only checks that the file exists and never cleans the name. 2The applicationpasses that filepath tonodewhisper()convertToWavType() pastes the path into an ffmpeg command string — The 0.3.1 code does not escape the path and hands the string to a shell through shelljs exec(). 3convertToWavType()pastes the pathinto an ffmpegcommand stringThe shell runs part of the file name as a command — According to the researcher, the injected command runs before transcription, whether or not ffmpeg succeeds, with the Node.js process's privileges. 4The shell runspart of the filename as a commandAttack pathCan be stopped herePlainCVE · plaincve.date/en/vulns/cve-2026-110644-nodejs-whisper-command-injection · CC BY 4.0
nodejs-whisper command injection: a crafted audio file name can run system commands on the server: 1. Uploads an audio file with a specially crafted name → 2. The application passes that file path to nodewhisper() → 3. convertToWavType() pastes the path into an ffmpeg command string → 4. The shell runs part of the file name as a commandCVE-2026-110644 · nodejs-whisper commandinjection: a crafted audio file name canrun system commands on the serverUploads an audio file with a specially crafted name — This only matters if the application keeps the user-supplied original file name. 1AttackerUploads an audio file with aspecially crafted nameThe application passes that file path to nodewhisper() — nodewhisper(filePath, options) is the package's public API; the package only checks that the file exists and never cleans the name. 2Your systemThe application passes thatfile path to nodewhisper()convertToWavType() pastes the path into an ffmpeg command string — The 0.3.1 code does not escape the path and hands the string to a shell through shelljs exec(). 3Your systemconvertToWavType() pastes thepath into an ffmpeg commandstringThe shell runs part of the file name as a command — According to the researcher, the injected command runs before transcription, whether or not ffmpeg succeeds, with the Node.js process's privileges. 4Your systemThe shell runs part of the filename as a commandAttack pathCan be stopped herePlainCVE · CC BY 4.0plaincve.date/en/vulns/cve-2026-110644-nodejs-whisper-command-injection
Free to use in reporting and teaching under CC BY 4.0. Attribution is already on the image.
  1. Attacker

    Uploads an audio file with a specially crafted name

    This only matters if the application keeps the user-supplied original file name.

    Defense: Always store uploads under a server-generated name (such as a random ID).

  2. Your system

    The application passes that file path to nodewhisper()

    nodewhisper(filePath, options) is the package's public API; the package only checks that the file exists and never cleans the name.

    Defense: Don't let user-influenced strings into the file path; a third-party aggregator also suggests validating or sanitizing input first.

  3. Your system

    convertToWavType() pastes the path into an ffmpeg command string

    The 0.3.1 code does not escape the path and hands the string to a shell through shelljs exec().

    Defense: The fix proposed in PR #259: use execFileSync with an argument array, with no shell involved.

  4. Your system

    The shell runs part of the file name as a command

    According to the researcher, the injected command runs before transcription, whether or not ffmpeg succeeds, with the Node.js process's privileges.

    Defense: Run the transcription service under a least-privilege account or container to limit the damage (PlainCVE suggestion).

Who is affected

nodejs-whisper is a speech transcription package on npm (the Node.js package registry), published by ChetanXpro.

ConditionAffected?
nodejs-whisper up to and including 0.3.1 + a user-influenced file name passed to nodewhisper()Affected
0.3.0, as tested by the researcherConfirmed to trigger
File names fully generated by the server (such as random IDs)The attacker can’t control the name; in our analysis the risk drops sharply, but it is still an affected version
Fixed versionUnconfirmed: no source names a fixed release

The researcher says the realistic exposure is an application that saves uploaded audio under its original file name and passes that path to nodewhisper(). The file must actually exist, because the package only checks that it does.

About “no login needed”: the CNA’s CVSS score lists required privileges as none and the attack vector as network. Our analysis: nodejs-whisper is a library, so whether an attacker needs to log in depends on how the application using it accepts file names. “Unauthenticated” is a scoring assumption, not true of every deployment.

How it works

Before transcribing, the package’s convertToWavType() calls ffmpeg (a common audio/video conversion tool) to turn the audio into WAV. In the 0.3.1 code, the file path is pasted straight into a command string without escaping, and the string is handed to a shell (the program that reads text commands) through shelljs exec().

The shell treats certain special characters as syntax. If a file name hides such characters, part of the name gets run as a separate command, with the Node.js process’s privileges. According to the researcher, that command runs before transcription starts, and whether or not ffmpeg itself succeeds. This weakness maps to CWE-78 (OS command injection).

The flawed approach (conceptual illustration, not the original source code):

Show code example(js)
// The path is pasted into a string, and the whole string is interpreted by a shell
const command = `ffmpeg -i "${filePath}" ... output.wav`
shell.exec(command)

The approach proposed in PR #259 (conceptual illustration; the PR #259 page contains attack code, so we don’t link it):

Show code example(js)
// No shell; the file name is just one value in an argument array, always treated as data
execFileSync('ffmpeg', ['-i', filePath, /* ... */ 'output.wav'])

Timeline

DateEvent
2026-06-23The researcher opens PR #259, publicly describing the issue and proposing a fix (that page contains attack code, so we don’t link it); the CNA’s CVE record also lists this as the public date
2026-10-14VulnCheck publishes the CVE record; CISA’s SSVC assessment rates exploitation as none and the issue as automatable
2026-10-15Not listed in CISA KEV

Further reading

  • Scoring: the CNA gives 9.8 under CVSS 3.1 and 9.3 under CVSS 4.0, both Critical; the difference comes from the scoring version.
  • Exploitation: not in CISA KEV as of 2026-10-15, and no exploitation in the wild has been reported; there is no evidence about exploitation before a fix. However, PR #259 is public and includes the file name the researcher used to confirm the issue (that page contains attack code, so we don’t link it), and CISA rates the issue as automatable.
  • Whether PR #259 has been merged or released cannot be confirmed from the sources.
  • Credited finder: Zachariah Mithani (per the VulnCheck advisory).
  • Related weakness type: CWE-78.

Verification Checked item by item against sources by AI under our review rules, all passed; not human-reviewed and not yet reproduced in our lab

AI review2026-10-15 · review rules

Verification records describe the environment and the result only, never reproduction steps or code that could attack other people’s systems. See our policy.

Sources

  1. CVE / NVD / OSVCVE-2026-110644 Record (CVE Services API) · CVE Program / VulnCheck (CNA), 2026-10-14 · accessed 2026-10-15
  2. Advisorynodejs-whisper through 0.3.1 OS Command Injection via convertToWavType · VulnCheck, 2026-10-14 · accessed 2026-10-15
  3. Vendornodejs-whisper v0.3.1 src/utils.ts · ChetanXpro (GitHub) · accessed 2026-10-15
  4. OtherCVE-2026-110644: Improper Neutralization of Special Elements used in an OS Command · OffSeq Radar · accessed 2026-10-15

Press brief

In one sentence

nodejs-whisper is an npm package used for speech transcription. In versions up to and including 0.3.1, it puts the file path straight into a command run by a shell when converting audio, so if an application passes a user-influenced file name (for example, an upload saved under its original name) to the package, a crafted file name can run arbitrary system commands on the server. The CNA scores it 9.3 under CVSS 4.0; as of October 15, 2026, it is not in CISA's Known Exploited Vulnerabilities catalog and no exploitation has been reported. No fixed version is confirmed.

Key facts

Severity
CVSS 4.0 9.3 / CVSS 3.1 9.8 (CNA) cveawg.mitre.org
Affected versions
Up to and including 0.3.1 cveawg.mitre.org
First public
2026-06-23 (public date in the CVE record; the researcher reported it publicly in a project PR, which contains attack code, so we don't link it) cveawg.mitre.org
CVE published
2026-10-14, by VulnCheck cveawg.mitre.org
Credited finder
Zachariah Mithani vulncheck.com

Confirmed

  • The 0.3.1 code puts the file path into an ffmpeg command without escaping and runs it through shelljs exec().
  • The researcher confirmed the injection on the published 0.3.0 release.
  • Not in CISA KEV as of 2026-10-15; CISA's SSVC assessment rates exploitation as 'none'.

Unconfirmed / disputed

  • Whether a fixed version exists: no source names one, and it can't be confirmed whether PR #259 was merged or released.
  • No advisory, changelog or release note from the maintainer (ChetanXpro) appears in the sources we reviewed.
  • Whether it was exploited before a fix existed (zero-day): there is no evidence either way.

Quotable line

A file name should only ever be a name, but here it becomes a command that gets run.

Images

Download the share image (PNG) · Attack flow diagram (downloadable)

Please credit "PlainCVE" and link to this page. Full citation format is under "How to cite" below. Found a factual error? Report it.

How to cite this page

This article is CC BY 4.0. Please keep the attribution and link when republishing.

PlainCVE Team (2026). "nodejs-whisper command injection: a crafted audio file name can run system commands on the server". PlainCVE. https://plaincve.date/en/vulns/cve-2026-110644-nodejs-whisper-command-injection (accessed YYYY-MM-DD)
BibTeX
@misc{cve2026110644nodejswhispercommandinjection2026,
  title  = {nodejs-whisper command injection: a crafted audio file name can run system commands on the server},
  author = {PlainCVE Team},
  year   = {2026},
  howpublished = {PlainCVE},
  url    = {https://plaincve.date/en/vulns/cve-2026-110644-nodejs-whisper-command-injection},
  note   = {Updated 2026-10-15}
}