Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦 npm
Not in CISA KEV

CVE-2026-86540 — knowns

Fix: knowns-dev/knowns@d398982

CVE-2026-86540 is a OS Command Injection vulnerability in knowns. A fix is available for knowns — see the affected versions and patch details below.

knowns before 0.30.0 Arbitrary Code Execution via LSP Binary

Also known asGHSA-mc52-mwq4-vfx3
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 23, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-86540.

EPSS Exploitation Probability

via FIRST.org ↗
0.2%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs11th percentile — riskier than 11% of all scored CVEsHighest risk
0.00%0.24%0.47%0.71%0.2%0.2%Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

0other npm packages depend on this — each one inherits the vulnerability until it's patched upstream
knownsnpm
62downloads / week

Description

Overview

A critical Arbitrary Code Execution (ACE) vulnerability exists in the Knowns Language Server Protocol (LSP) detection and startup pipeline. The system blindly trusts the settings.lsp.languages.<lang>.binary field defined in the project-level .knowns/config.json file.

Because this field is never validated against an allowlist of managed binaries, and absolute paths are implicitly accepted, opening a malicious repository (or a legitimate repository where the config has been tampered with) results in the immediate execution of an attacker-controlled binary. The payload is executed twice per session: once during the initial runVersionCheck (health check), and again when the LSP server process is spawned via Server.Start(). When chained with the previously identified Config Overwrite vulnerabilities, this flaw yields a fully unauthenticated Remote Code Execution chain.

Affected paths

File PathRoleVulnerability & Execution Impact
internal/models/config.goValidation GapMissing Binary Validation (CWE-829): ProjectSettings.Validate() enforces duration formats for task lifecycles but completely ignores the LSPLanguageSettings.Binary field. Absolute paths, shell interpreters, and untrusted executables are silently accepted.
internal/lsp/detect.goExecution Sink #1Unsanitized Health Check Execution: Detector.resolve() passes the unvalidated override to exec.LookPath(), then invokes runVersionCheck() which blindly calls cmd.Run() on the attacker-controlled binary with CheckArgs.
internal/lsp/server.goExecution Sink #2Unsanitized LSP Server Spawn: Server.Start() passes the resolved binary path to knownsprocess.Command() and spawns it as a long-running background process via cmd.Start(), executing the payload a second time.

Root Cause

Missing Validation in Configuration Schema

In internal/models/config.go, the ProjectSettings.Validate() function is responsible for sanitizing the project configuration loaded from .knowns/config.json. However, it only validates task lifecycle durations:

func (s ProjectSettings) Validate() error {
    settings := s.EffectiveTaskLifecycle()
    if _, err := ParseTaskLifecycleDuration(settings.ArchiveAfter); err != nil { ... }
    // NO VALIDATION FOR s.LSP.Languages[lang].Binary
    return nil
}

The LSPLanguageSettings struct exposes a Binary string field. When a malicious project is loaded, this string is passed unmodified into the LSP resolution pipeline.

Blind Execution in LSP Detector

In internal/lsp/detect.go, the Detector.resolve() function accepts an override string (from the config) and forces it into the execution pipeline:

func (d *Detector) resolve(ctx context.Context, root string, lang Language, override string) (ServerCommand, bool) {
    binaries := lang.Binaries
    if override != "" {
        binary := Binary{Name: override} // Attacker's malicious path injected here
        binaries = []Binary{binary}
    }
    for _, binary := range binaries {
        path, err := d.LookPath(binary.Name) // Accepts absolute paths (e.g., /tmp/evil.sh)
        // ...
        err = d.RunCheck(checkCtx, path, binary.CheckArgs...) // EXECUTION #1
        // ...
    }
}

d.RunCheck maps to runVersionCheck, which executes the binary via knownsprocess.CommandContext(ctx, path, args...).Run().

Unrestricted Process Spawn

In internal/lsp/server.go, when the LSP manager starts the server, it executes the same compromised path:

func (s *Server) Start(ctx context.Context) error {
    // ...
    cmd := knownsprocess.Command(s.Command.Path, s.Command.Args...) // EXECUTION #2
    cmd.Dir = s.Root
    // ...
    if err := cmd.Start(); err != nil { ... }
}

Attack Vector

PhaseRequest / ActionEffect
1. PlantAttacker commits .knowns/config.json containing {"settings":{"lsp":{"languages":{"go":{"binary":"/tmp/evil.sh"}}}}} to a repository.Malicious config embedded in the project.
2. TriggerVictim (or AI Agent) clones the repo and opens it with knowns mcp or knowns browser.Auto-detection scans the project, finds a .go file, and loads the malicious config.
3. Execute (Health Check)Detector.resolve() calls runVersionCheck("/tmp/evil.sh", "version").RCE Execution #1 occurs silently in the background.
4. Execute (LSP Spawn)Server.Start() calls cmd.Start() with the same binary.RCE Execution #2 occurs, spawning the malicious process as a long-running daemon.

Chained Attack Vector (Unauthenticated RCE): If combined with the Config Overwrite vulnerability (via code.replace path traversal), a remote attacker can overwrite .knowns/config.json in a target project, inject a payload, and trigger an LSP restart (via docs.update or server reload), achieving Remote Code Execution without any user interaction.

Analysis

This vulnerability is a textbook example of Inclusion of Functionality from Untrusted Control Sphere (CWE-829), commonly known in the IDE/Editor space as the "Malicious Workspace" vulnerability (similar to historical CVEs in VS Code where .vscode/settings.json could point to malicious interpreter paths).

The core failure is the lack of a strict allowlist for executable paths. By relying on exec.LookPath(), the code allows an attacker to bypass binary name resolution simply by providing an absolute path (/abs/path/evil.sh) or a path containing a slash (./evil.sh).

Furthermore, the execution happens automatically upon project load. In modern AI-driven development workflows, AI Agents automatically scan project files (like .go, .ts, .py) to provide context. The LSP detector triggers on file extensions, meaning the victim or agent does not even need to explicitly run a "build" or "start" command; the mere act of the Agent indexing the workspace triggers the payload.

Fix

Patch is available right now at New Release.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npmknownsall versions0.30.0npm install knowns@0.30.0

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for knowns, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update knowns to 0.30.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-86540 is resolved across your whole dependency graph.

  3. Workarounds

    Stop passing untrusted input into the interpreter or shell: call the affected binary with an argument array rather than a composed command string, reject anything outside a strict allowlist of expected values, and run the component under an account that cannot reach beyond the work it legitimately does.

Frequently Asked Questions

## Overview A critical **Arbitrary Code Execution (ACE)** vulnerability exists in the Knowns Language Server Protocol (LSP) detection and startup pipeline. The system blindly trusts the `settings.lsp.languages.<lang>.binary` field defined in the project-level `.knowns/config.json` file. Because this field is **never validated** against an allowlist of managed binaries, and absolute paths are implicitly accepted, opening a malicious repository (or a legitimate repository where the config has been tampered with) results in the immediate execution of an attacker-controlled binary. The payload
O3 Security · Impact-Aware SCA

Is CVE-2026-86540 in your dependencies?

Find it across npm, including transitive dependencies.

CVE-2026-86540: knowns RCE — Fixed in 0.30.0