From 633802eee2b42951c4e1b75c9dc438fd4f1deb4d Mon Sep 17 00:00:00 2001
From: coreybutler <770982+coreybutler@users.noreply.github.com>
Date: Mon, 19 Oct 2026 20:53:26 -0500
Subject: [PATCH] docs: describe the malware feed client
The codes, notifications, cache commands, and policy keys need a page before the client ships.
---
docs/cfg/core.md | 4 +++-
docs/cfg/enterprise/registry.md | 8 +++++++
docs/command/nvm/cache/list.md | 2 +-
docs/command/nvm/cache/remove/all.md | 2 +-
docs/command/nvm/cache/remove/index.md | 3 ++-
docs/command/nvm/cache/remove/malware.md | 24 +++++++++++++++++++
docs/features/cache.md | 4 ++++
docs/features/log.md | 9 +++++++
docs/features/notifications.md | 2 ++
docs/guide/firewall.md | 2 ++
docs/troubleshooting/error-codes.md | 3 +++
.../current/cfg/enterprise/registry.md | 8 +++++++
12 files changed, 67 insertions(+), 4 deletions(-)
create mode 100644 docs/command/nvm/cache/remove/malware.md
diff --git a/docs/cfg/core.md b/docs/cfg/core.md
index 9d2644b..cc66de0 100644
--- a/docs/cfg/core.md
+++ b/docs/cfg/core.md
@@ -94,7 +94,9 @@ nvm config set auto_detect=.nvmrc,.node-version
| Option | Default | Values | Description |
|--------|---------|--------|-------------|
| `log_executions` | `false` | Boolean | Whether to log every Node.js invocation (ex: `node file.js`). (shim-only) |
-| `disable_announcements` | `false` | Boolean | Whether to disable project and release announcements. On Certified Builds, license expiry warnings still run when a commercial license is present. |
+| `disable_announcements` | `false` | Boolean | Whether to disable project and release announcements. On Certified Builds, license expiry warnings still run when a commercial license is present. This does not suppress malware definition or malware block notifications. |
+| `skip_malware_checks` | `false` | Boolean | Skip malware checks for package-manager and node shims. The definition file still updates. HKLM `SkipMalwareChecks` wins over HKCU. |
+| `notify_malware_definitions` | `true` | Boolean | Certified only. Show a silent notification after malware definitions change. HKLM can force it off. |
```powershell
nvm config set log_executions=true
diff --git a/docs/cfg/enterprise/registry.md b/docs/cfg/enterprise/registry.md
index 72ade45..8356581 100644
--- a/docs/cfg/enterprise/registry.md
+++ b/docs/cfg/enterprise/registry.md
@@ -52,6 +52,11 @@ See [Administrative Templates](ad) for GPO and Intune deployment. Download ADMX/
|**Local install source**|`LocalInstallDir`|**Overridable** (`local_dir`). Alternate local directory for Node.js archives (air-gapped mirrors). Overrides cache.
`REG_SZ`|
|**Local install only**|`LocalInstallOnly`|**Overridable** (`local_install_only`). Restrict installs to `LocalInstallDir` only.
- `0` = off
- `1` = on
Default: `0`
`REG_DWORD`|
|**Audit logging**|`LogExecutions`|**Overridable** (`log_executions`). Log every Node.js invocation to the Windows Event Log (shim-only). Most useful on **Audit+** (structured ETW).
- `0` = off
- `1` = on
Default: `0`
`REG_DWORD`|
+|**Skip malware checks**|`SkipMalwareChecks`|**Overridable** (`skip_malware_checks`). Skip malware checks for package-manager and node shims. The definition file still updates. HKLM wins over HKCU.
- `0` = check
- `1` = skip
Default: `0`
`REG_DWORD`|
+|**Notify malware definitions**|`NotifyMalwareDefinitions`|**Overridable** (`notify_malware_definitions`). Certified only. Silent toast after definitions change. HKLM can force it off.
- `0` = hide
- `1` = show
Default: `1`
`REG_DWORD`|
+|**Malware allow list**|`MalwareAllowList`|HKLM only. Patterns that clear an OpenSSF hit. Byte-for-byte. A `*` clears every OpenSSF hit. Does not clear an organization block. Empty allows nothing.
`REG_MULTI_SZ`|
+|**Malware block list**|`MalwareBlockList`|Certified only. HKLM patterns that always block, or one `https://` policy URL. Community builds ignore this list.
`REG_MULTI_SZ`|
+|**Malware trust conflict**|`MalwareTrustConflict`|Certified only. **Overridable** (`malware_trust_conflict`). `prevent` (default) blocks a trusted or approved OpenSSF hit. `continue` lets that explicit trust or approval through. HKLM wins over HKCU.
`REG_SZ`|
|**Node.js download mirrors**|`MirrorNode`|**Overridable** (`node_mirror`). Ordered mirror list; first successful response wins. See [Download Mirrors](../features/mirrors). Author `*.author.io` mirrors need Governance licensing — see [Version Firewall + Author Mirror](../features/author-mirror).
Default: `https://nodejs.org/dist`
`REG_MULTI_SZ`|
|**npm registry mirrors**|`MirrorNpm`|**Overridable** (`npm_mirror`). Ordered npm registry list. Used as shim registry fallback.
Default: `https://registry.npmjs.org`
`REG_MULTI_SZ`|
|**Operating mode**|`OperatingMode`|**Overridable** (`mode`). How NVM for Windows manages Node.js versions.
**Shim** (recommended) uses signed shims to intercept `node`, `npm`, `npx`, `yarn`, and `pnpm`. Required for runtime policies (audit logging, auto-detect, ACL).
**Link** uses NTFS junctions/symlinks on PATH.
Default: `shim`
`REG_SZ`|
@@ -126,6 +131,9 @@ Windows Registry Editor Version 5.00
"FirewallSkipLockfile"=dword:00000000
"DisableUpgrade"=dword:00000001
"DisableAnnouncements"=dword:00000001
+"SkipMalwareChecks"=dword:00000000
+"NotifyMalwareDefinitions"=dword:00000001
+"MalwareTrustConflict"="prevent"
; --- Shim runtime (requires OperatingMode=shim) ---
"DefaultDetectFile"=".nvmrc"
diff --git a/docs/command/nvm/cache/list.md b/docs/command/nvm/cache/list.md
index fe32eb6..8b26482 100644
--- a/docs/command/nvm/cache/list.md
+++ b/docs/command/nvm/cache/list.md
@@ -19,7 +19,7 @@ nvm cache list [name ...] [flags]
| Argument | Required | Description |
|----------|----------|-------------|
-| `[name ...]` | No | Filter by cache name (for example `versions`, `metadata`). |
+| `[name ...]` | No | Filter by cache name (for example `versions`, `metadata`, `malware`). `malware` lists one row per lockfile stamp plus `malware.db`. |
## Flags
diff --git a/docs/command/nvm/cache/remove/all.md b/docs/command/nvm/cache/remove/all.md
index 9d115f5..dd3c4cc 100644
--- a/docs/command/nvm/cache/remove/all.md
+++ b/docs/command/nvm/cache/remove/all.md
@@ -5,7 +5,7 @@ sidebar_position: 3
# nvm cache remove all
-Clear both metadata and versions caches.
+Clear metadata, versions, malware scan stamps, and `malware.db`.
## Usage
diff --git a/docs/command/nvm/cache/remove/index.md b/docs/command/nvm/cache/remove/index.md
index 624ec78..73c1bbd 100644
--- a/docs/command/nvm/cache/remove/index.md
+++ b/docs/command/nvm/cache/remove/index.md
@@ -15,7 +15,8 @@ Remove cached artifacts.
|------------|-------------|
| [`version`](./version) | Remove cached Node.js archives (default). |
| [`metadata`](./metadata) | Remove cached metadata files. |
-| [`all`](./all) | Clear metadata and versions caches. |
+| [`all`](./all) | Clear metadata, versions, malware stamps, and `malware.db`. |
+| [`malware`](./malware) | Remove malware scan stamps, or `malware.db` when you pass that path. |
## Notes
diff --git a/docs/command/nvm/cache/remove/malware.md b/docs/command/nvm/cache/remove/malware.md
new file mode 100644
index 0000000..16ac0bd
--- /dev/null
+++ b/docs/command/nvm/cache/remove/malware.md
@@ -0,0 +1,24 @@
+---
+title: malware
+sidebar_position: 4
+---
+
+# nvm cache remove malware
+
+Remove malware scan stamps. With no path, every stamp is removed and `malware.db` stays. A path removes that stamp. `--prompt` can also select `malware.db`.
+
+`nvm cache remove all` removes the stamps and `malware.db`.
+
+## Usage
+
+```powershell
+nvm cache remove malware [path ...] [flags]
+```
+
+## Flags
+
+| Flag | Short | Description |
+|------|-------|-------------|
+| `--prompt` | `-p` | Pick stamps, `malware.db`, or both. |
+
+Removal honors [`allow_download_cache_removal`](../../../../cfg/core#downloads-and-mirrors).
diff --git a/docs/features/cache.md b/docs/features/cache.md
index b7d85f4..3a87364 100644
--- a/docs/features/cache.md
+++ b/docs/features/cache.md
@@ -31,6 +31,7 @@ Under the NVM data root (parent of the install root; default `%LOCALAPPDATA%\Aut
|-------|------|----------|
| Versions | `.cache/versions` | Node.js `.7z` archives (`node-v{version}-win-{x64\|arm64}.7z`) |
| Metadata | `.cache/metadata` | Sync/release index metadata (not install archives) |
+| Malware scans | `.cache/malware-scan` | One stamp per scanned lockfile. `malware.db` itself lives in the data root, next to this `.cache` directory |
| HTTP | `.cache/http` | Short-lived HTTP bodies (for example SHASUM fetches) |
If [`local_dir`](../cfg/registry#available-registry-keys) is set (see [registry policy](../cfg/registry)), that directory **replaces** `.cache/versions` as the archive source for installs.
@@ -54,6 +55,9 @@ nvm cache # list (alias: nvm cache list/ls)
nvm cache add 24 lts # prefetch archives
nvm cache remove version 24.1.0
nvm cache remove metadata
+nvm cache list malware
+nvm cache remove malware
+nvm cache remove malware --prompt
nvm cache remove all
nvm list cached # versions view of cached archives
```
diff --git a/docs/features/log.md b/docs/features/log.md
index c3cb294..c4bd289 100644
--- a/docs/features/log.md
+++ b/docs/features/log.md
@@ -19,3 +19,12 @@ If setup cannot elevate for `nvm --register-eventlog` (UAC canceled / non-admin)
:::tip[Certified Builds — Advanced Logging]
The **Advanced Logging** add-on (Certified Builds, available September 2026) writes structured entries with well-known SIEM event codes to a dedicated native NVM for Windows log (not the Application log). Use it for fleet SIEM integration and audit querying.
:::
+
+## Malware feed
+
+These events are written only when advanced logging is on. They use Windows Event ID 120 on `NVM for Windows/Operational`. A block still prints in the terminal when that license is off, and that block does not write `package_manager.install`.
+
+| Code | Event | Payload |
+|------|--------|---------|
+| **NVM4601** | `malware.definitions_updated` | `added`, `removed`, `seq`, `previous_seq` |
+| **NVM4602** | `malware.package_blocked` | package name, version when known, command |
diff --git a/docs/features/notifications.md b/docs/features/notifications.md
index 9221f08..346c57c 100644
--- a/docs/features/notifications.md
+++ b/docs/features/notifications.md
@@ -52,3 +52,5 @@ Scheduled maintenance can also display notifications:
| News feed | Feed entry title | Body is the entry description with links; skipped when [`disable_announcements`](../cfg/core#logging-and-announcements) is true |
| Update available | Update Available | Version availability with View/Upgrade links; skipped when [`disable_announcements`](../cfg/core#logging-and-announcements) is true |
| License expiry
_(certified builds)_ | Expiration warning | Not suppressed by [`disable_announcements`](../cfg/core#logging-and-announcements); at most one notification per milestone/day. |
+| Malware definitions
_(certified builds)_ | Malware definitions updated | Silent. Body is the added and removed counts. **Don't show again** sets `notify_malware_definitions` to false. Not suppressed by [`disable_announcements`](../cfg/core#logging-and-announcements). |
+| Malware block, console in the background | Malicious package blocked | Audible (`Notification.Reminder`). Names at most three packages, then `and N more`. Not suppressed by [`disable_announcements`](../cfg/core#logging-and-announcements). On a community build joined to Active Directory, Entra, or Google Workspace, the body adds: `Certified keeps a record of blocks like this for your security tools.` |
diff --git a/docs/guide/firewall.md b/docs/guide/firewall.md
index de03fb9..ef63979 100644
--- a/docs/guide/firewall.md
+++ b/docs/guide/firewall.md
@@ -16,6 +16,8 @@ Frontline controls for Node version installs, npm package installs, and self-upd
| Version | Certified | `VersionAllowList` / `VersionBlockList` | Block `nvm install` of disallowed Node versions |
| Module | Certified | `ApprovedModules` / `ApprovedGlobalModules` | Block npm/pnpm/yarn/npx install of disallowed packages (shim mode) |
| Trust | Community + Certified | `TrustedModules`, `UntrustedModuleHandlerAction` | Auto-reshim or prompt when a global CLI self-updates |
+| Malware, surface | Community + Certified | `SkipMalwareChecks`, `MalwareAllowList` | Block an OpenSSF hit on the named package or on direct `package.json` dependencies. Default on |
+| Malware, lockfile | Certified | `MalwareBlockList`, `MalwareTrustConflict` | Also scan the lockfile. An organization block list and trust conflict apply only here |
## Commands
diff --git a/docs/troubleshooting/error-codes.md b/docs/troubleshooting/error-codes.md
index 9df877a..8eca186 100644
--- a/docs/troubleshooting/error-codes.md
+++ b/docs/troubleshooting/error-codes.md
@@ -33,6 +33,8 @@ NVM for Windows uses stable `NVM####` codes in CLI messages, shim/proxy output,
| **NVM4408** | Module firewall allowed install | Audit (non-error): proxy evaluated module policy and allowed the install |
| **NVM4409** | Firewall remote authority unreachable | HTTPS policy host refused the connection, timed out, or could not be resolved |
| **NVM4410** | Firewall policy mutated | Audit: `nvm firewall` changed a policy list |
+| **NVM4601** | Malware definitions updated | Informational, advanced logging only. A successful `malware.db` write changed the database. Payload: `added`, `removed`, `seq`, `previous_seq`. Windows Event ID 120 |
+| **NVM4602** | Malicious package blocked | Informational, advanced logging only. The shim blocked a package before the install audit. Payload includes the package name, version when known, and command. The terminal message still prints without the advanced logging license. Windows Event ID 120 |
## Ranges
@@ -41,6 +43,7 @@ NVM for Windows uses stable `NVM####` codes in CLI messages, shim/proxy output,
| **NVM41xx** | Installer / Community layout and support boundary |
| **NVM43xx** | Runtime Node trust, activation, auto-install, and package-manager gatekeeping |
| **NVM44xx** | NVM Firewall (version / module / trust policy) |
+| **NVM46xx** | Malware feed. Informational and advanced logging only |
## Tips
diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/cfg/enterprise/registry.md b/i18n/ru/docusaurus-plugin-content-docs/current/cfg/enterprise/registry.md
index a99c5f0..6f3f50b 100644
--- a/i18n/ru/docusaurus-plugin-content-docs/current/cfg/enterprise/registry.md
+++ b/i18n/ru/docusaurus-plugin-content-docs/current/cfg/enterprise/registry.md
@@ -43,6 +43,11 @@ certified:
|**Cache downloads**|`CacheDownloads`|**Overridable** (`cache_downloads`). Кэшировать загруженные версии Node.js для офлайн-использования.
- `0` = выкл./false
- `1` = вкл./true
По умолчанию: `0`
`REG_DWORD`|
|**Default detect file**|`DefaultDetectFile`|**Overridable** (`default_detect_file`). Файл, записываемый при закреплении версии (`nvm pin`) (только shim).
По умолчанию: `.nvmrc`
`REG_SZ`|
|**Disable announcements**|`DisableAnnouncements`|**Overridable** (`disable_announcements`). Скрыть объявления проекта и релизов.
- `0` = показывать
- `1` = скрывать
По умолчанию: `0`
`REG_DWORD`|
+|**Пропускать проверки malware**|`SkipMalwareChecks`|**Overridable** (`skip_malware_checks`). Не проверять пакеты и `node` по списку malware. Файл определений всё равно обновляется. HKLM важнее HKCU.
- `0` = проверять
- `1` = пропустить
По умолчанию: `0`
`REG_DWORD`|
+|**Уведомлять об обновлении определений**|`NotifyMalwareDefinitions`|**Overridable** (`notify_malware_definitions`). Только Certified. Тихое уведомление после смены определений. HKLM может отключить его.
- `0` = скрыть
- `1` = показать
По умолчанию: `1`
`REG_DWORD`|
+|**Список разрешённых malware-имён**|`MalwareAllowList`|Только HKLM. Шаблоны, которые снимают попадание OpenSSF. Сравнение по байтам. `*` снимает все попадания OpenSSF и не снимает блок организации.
`REG_MULTI_SZ`|
+|**Список блокировки malware**|`MalwareBlockList`|Только Certified. Шаблоны HKLM, которые всегда блокируют, или один URL `https://`. Community игнорирует этот список.
`REG_MULTI_SZ`|
+|**Конфликт доверия malware**|`MalwareTrustConflict`|Только Certified. **Overridable** (`malware_trust_conflict`). `prevent` (по умолчанию) блокирует доверенное или одобренное имя из OpenSSF. `continue` пропускает такое явное доверие. HKLM важнее HKCU.
`REG_SZ`|
|**Disallow eval/string code gen**|`DisableEvalAndStringExecution`|**Overridable** (`disable_eval_and_string_execution`). Shim добавляет `--disallow-code-generation-from-strings`, блокируя `eval()` и `new Function()` (только shim). Не влияет на `node:vm`.
- `0` = выкл.
- `1` = вкл.
По умолчанию: `0`
`REG_DWORD`|
|**Disable NVM upgrades**|`DisableUpgrade`|**Overridable.** Блокировать обновления NVM в приложении (не блокирует развёртывание пакетов AD/GPO).
- `0` = разрешено
- `1` = заблокировано
По умолчанию: `0`
`REG_DWORD`|
|**Disable version management**|`Enabled`|**Overridable** (`nvm on`/`nvm off`). Принудительно включает или отключает управление версиями. При выкл. NVM не управляет и не перенаправляет команды Node.js.
- `0` = выкл. (`nvm off`)
- `1` = вкл.
По умолчанию: `1`
`REG_DWORD`|
@@ -126,6 +131,9 @@ Windows Registry Editor Version 5.00
"FirewallSkipLockfile"=dword:00000000
"DisableUpgrade"=dword:00000001
"DisableAnnouncements"=dword:00000001
+"SkipMalwareChecks"=dword:00000000
+"NotifyMalwareDefinitions"=dword:00000001
+"MalwareTrustConflict"="prevent"
; --- Shim runtime (requires OperatingMode=shim) ---
"DefaultDetectFile"=".nvmrc"