{"schema":"threatline.record/2","record":{"id":"CVE-2026-86540","aliases":["GHSA-mc52-mwq4-vfx3"],"summary":"knowns OS Command Injection via Insecure LSP Binary Path Config in .knowns/config.json","details":"## Overview\n\nA 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. \n\nBecause 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.\n\n## Affected paths\n\n| File Path | Role | Vulnerability & Execution Impact |\n| :--- | :--- | :--- |\n| **`internal/models/config.go`** | Validation Gap | **Missing 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. |\n| **`internal/lsp/detect.go`** | Execution Sink #1 | **Unsanitized 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`. |\n| **`internal/lsp/server.go`** | Execution Sink #2 | **Unsanitized 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. |\n\n## Root Cause\n\n### Missing Validation in Configuration Schema\nIn `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:\n\n```go\nfunc (s ProjectSettings) Validate() error {\n    settings := s.EffectiveTaskLifecycle()\n    if _, err := ParseTaskLifecycleDuration(settings.ArchiveAfter); err != nil { ... }\n    // NO VALIDATION FOR s.LSP.Languages[lang].Binary\n    return nil\n}\n```\n\nThe `LSPLanguageSettings` struct exposes a `Binary` string field. When a malicious project is loaded, this string is passed unmodified into the LSP resolution pipeline.\n\n### Blind Execution in LSP Detector\nIn `internal/lsp/detect.go`, the `Detector.resolve()` function accepts an `override` string (from the config) and forces it into the execution pipeline:\n\n```go\nfunc (d *Detector) resolve(ctx context.Context, root string, lang Language, override string) (ServerCommand, bool) {\n    binaries := lang.Binaries\n    if override != \"\" {\n        binary := Binary{Name: override} // Attacker's malicious path injected here\n        binaries = []Binary{binary}\n    }\n    for _, binary := range binaries {\n        path, err := d.LookPath(binary.Name) // Accepts absolute paths (e.g., /tmp/evil.sh)\n        // ...\n        err = d.RunCheck(checkCtx, path, binary.CheckArgs...) // EXECUTION #1\n        // ...\n    }\n}\n```\n\n`d.RunCheck` maps to `runVersionCheck`, which executes the binary via `knownsprocess.CommandContext(ctx, path, args...).Run()`.\n\n### Unrestricted Process Spawn\nIn `internal/lsp/server.go`, when the LSP manager starts the server, it executes the same compromised path:\n\n```go\nfunc (s *Server) Start(ctx context.Context) error {\n    // ...\n    cmd := knownsprocess.Command(s.Command.Path, s.Command.Args...) // EXECUTION #2\n    cmd.Dir = s.Root\n    // ...\n    if err := cmd.Start(); err != nil { ... }\n}\n```\n\n## Attack Vector\n\n| Phase | Request / Action | Effect |\n| :--- | :--- | :--- |\n| **1. Plant** | Attacker commits `.knowns/config.json` containing `{\"settings\":{\"lsp\":{\"languages\":{\"go\":{\"binary\":\"/tmp/evil.sh\"}}}}}` to a repository. | Malicious config embedded in the project. |\n| **2. Trigger** | Victim (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. |\n| **3. Execute (Health Check)** | `Detector.resolve()` calls `runVersionCheck(\"/tmp/evil.sh\", \"version\")`. | **RCE Execution #1** occurs silently in the background. |\n| **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. |\n\n**Chained Attack Vector (Unauthenticated RCE):**\nIf 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**.\n\n## Analysis\n\nThis 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).\n\nThe 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`). \n\nFurthermore, 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.\n\n## Fix\n\n*Patch is available right now at [New Release](https://github.com/knowns-dev/knowns/releases).*","categories":["Libraries & packages"],"product":"knowns","vendor":"knowns-dev","ecosystem":"npm","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-mc52-mwq4-vfx3","source_modified_at":"2026-10-06T18:58:40Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"knowns"},"range":"<= 0.29.1"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-86540","source_modified_at":"2026-09-24T14:21:24.010Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"knowns","vendor":"knowns-dev","versions":[{"version":"0","status":"affected","versionType":"semver","lessThan":"0.30.0"},{"version":"0.30.0","status":"unaffected","versionType":"semver"}],"defaultStatus":"unaffected"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-mc52-mwq4-vfx3","source_modified_at":"2026-10-06T19:15:03.494654433Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"knowns","purl":"pkg:npm/knowns"},"ranges":[{"events":[{"introduced":"0"},{"fixed":"0.30.0"}],"type":"SEMVER"}],"versions":[]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-mc52-mwq4-vfx3","source_modified_at":"2026-10-06T18:58:40Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"knowns"},"version":"0.30.0"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-86540","source_modified_at":"2026-09-24T14:21:24.010Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"knowns","ecosystem":null},"version":"0.30.0","basis":"first unaffected version stated in the CVE record"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-mc52-mwq4-vfx3","source_modified_at":"2026-10-06T19:15:03.494654433Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"knowns","purl":"pkg:npm/knowns"},"version":"0.30.0"}],"cvss":7.8,"severity":"High","kev":{"listed":false},"epss":{"probability":0.00212,"percentile":0.1097,"score_date":"2026-10-23"},"published_at":"2026-09-07T23:03:18.654Z","modified_at":"2026-10-06T19:15:03.494654433Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-mc52-mwq4-vfx3","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-06T18:58:40Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-86540","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-09-24T14:21:24.010Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-mc52-mwq4-vfx3","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-06T19:15:03.494654433Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-86540","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/knowns-dev/knowns/security/advisories/GHSA-mc52-mwq4-vfx3","tags":["vendor-advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-86540","source":"GitHub Advisory Database"},{"source":"CVE List","url":"https://github.com/knowns-dev/knowns/commit/d3989829fb5095666d23d005b2f78a082832a396","tags":["patch"]},{"source":"CVE List","url":"https://github.com/knowns-dev/knowns/blob/v0.29.1/internal/lsp/detect.go#L128-L157","tags":["technical-description"]},{"source":"CVE List","url":"https://github.com/knowns-dev/knowns/blob/v0.29.1/internal/models/config.go#L205-L216","tags":["technical-description"]},{"source":"CVE List","url":"https://github.com/knowns-dev/knowns/releases/tag/v0.30.0","tags":["release-notes"]},{"source":"CVE List","url":"https://www.vulncheck.com/advisories/knowns-before-0.30.0-arbitrary-code-execution-via-lsp-binary","tags":["third-party-advisory"]},{"url":"https://github.com/advisories/GHSA-mc52-mwq4-vfx3","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"poc","automatable":"no","technical_impact":"total","assessed_at":"2026-09-08T13:48:43.528505Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-06T19:15:03.494654433Z","content_hash":"4e912e8b505e4cc4fac9e757d3b5a103cf258fa738201a0684157dd738f0cacb"}}
