openclaw-plugin-vt-sentinel 0.12.2 → 0.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -7
- package/CODE_OF_CONDUCT.md +53 -0
- package/CONTRIBUTING.md +63 -0
- package/LICENSE +21 -0
- package/README.md +4 -3
- package/SECURITY.md +57 -0
- package/dist/classifier.d.ts +1 -1
- package/dist/classifier.js +1 -1
- package/dist/compliance-snapshot.js +3 -3
- package/dist/env-access.d.ts +1 -2
- package/dist/env-access.js +1 -2
- package/dist/index.js +7 -7
- package/dist/path-extractor.js +1 -1
- package/dist/signatures/dangerous-commands.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +18 -9
- package/skills/vt-sentinel/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `openclaw-plugin-vt-sentinel`.
|
|
4
4
|
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
|
+
|
|
8
|
+
## 0.12.3 — Dependency hygiene + OSS polish
|
|
9
|
+
|
|
10
|
+
No runtime behavior changes. Pure housekeeping release.
|
|
11
|
+
|
|
12
|
+
### Security
|
|
13
|
+
|
|
14
|
+
- Bumped `axios` past GHSA-3p68-rc4w-qgx5 and GHSA-fvcv-3m26-pcqx (critical).
|
|
15
|
+
- Bumped `follow-redirects` past GHSA-r4q5-vmmm-2653 (moderate, header leak
|
|
16
|
+
on cross-domain redirects).
|
|
17
|
+
- Bumped `picomatch` past GHSA-3v7f-55p6-f55p and GHSA-c2c7-rcm5-vvqj
|
|
18
|
+
(high, method injection + ReDoS).
|
|
19
|
+
- `npm audit --package-lock-only` now reports `found 0 vulnerabilities`.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- `LICENSE` (MIT).
|
|
24
|
+
- `SECURITY.md` with private vulnerability reporting process.
|
|
25
|
+
- `CONTRIBUTING.md` with build/test/release workflow.
|
|
26
|
+
- `CODE_OF_CONDUCT.md` (Contributor Covenant 2.1).
|
|
27
|
+
- `engines.node` declaration (`">=18"`) in `package.json`.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- `package.json`: corrected `homepage` to point at the repository (was
|
|
32
|
+
pointing at the VTAI backend service), added `author` and refreshed
|
|
33
|
+
`openclaw.build.openclawVersion`.
|
|
34
|
+
- `README.md`: fixed a stale reference to the ClawHub host.
|
|
35
|
+
- Changelog now follows Keep a Changelog headings.
|
|
36
|
+
|
|
5
37
|
## 0.12.2 — Audit collector accuracy + legacy log sanitization
|
|
6
38
|
|
|
7
39
|
Small follow-up to 0.12.1. The static collector could only see
|
|
@@ -36,8 +68,8 @@ Fix for the collector introduced in 0.12.0. The in-gateway registration via
|
|
|
36
68
|
`api.registerSecurityAuditCollector` was insufficient: `openclaw security audit
|
|
37
69
|
--deep` runs in a fresh Node process that doesn't share state with the gateway
|
|
38
70
|
and reads collectors from the plugin's **module-level** `securityAuditCollectors`
|
|
39
|
-
field instead. Verified
|
|
40
|
-
|
|
71
|
+
field instead. Verified on an integration environment (OpenClaw 2026.4.12):
|
|
72
|
+
0.12.0 shipped with a runtime-only collector that emitted zero
|
|
41
73
|
`vt-sentinel.*` findings under `openclaw security audit --deep --json`.
|
|
42
74
|
|
|
43
75
|
### Fixed
|
|
@@ -105,16 +137,16 @@ Both views are rendered from the same snapshot function, so they can't drift.
|
|
|
105
137
|
runtime path is sufficient. One authoritative source, half the
|
|
106
138
|
maintenance surface.
|
|
107
139
|
|
|
108
|
-
###
|
|
140
|
+
### Implementation notes
|
|
109
141
|
|
|
110
142
|
- `src/update-commands.ts` — split from `index.ts` in 0.11.3 for scanner
|
|
111
143
|
hygiene; now also used by the compliance snapshot tests as an example
|
|
112
|
-
of the
|
|
144
|
+
of the pure-helper pattern applied across the codebase.
|
|
113
145
|
|
|
114
146
|
### Deferred
|
|
115
147
|
|
|
116
|
-
- **Migration to `definePluginEntry`.** Verified empirically on
|
|
117
|
-
|
|
148
|
+
- **Migration to `definePluginEntry`.** Verified empirically on OpenClaw
|
|
149
|
+
2026.4.12 integration: `require('openclaw/plugin-sdk/core')`
|
|
118
150
|
does not resolve from `~/.openclaw/extensions/<plugin>/dist/`. Would
|
|
119
151
|
require a peerDependency + NODE_PATH surgery with only cosmetic benefit.
|
|
120
152
|
The plain default-export plugin shape stays. Re-evaluate when OpenClaw
|
|
@@ -307,7 +339,7 @@ scan, which requires no key. Both paths are fully supported.
|
|
|
307
339
|
|
|
308
340
|
## Earlier history
|
|
309
341
|
|
|
310
|
-
See git log
|
|
342
|
+
See git log for details on 0.5.0 through 0.10.0.
|
|
311
343
|
Highlights:
|
|
312
344
|
|
|
313
345
|
- **0.10.0** — SEMANTIC_RISK files (SKILL.md, HOOK.md, AGENTS.md) route
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Contributor Code of Conduct
|
|
2
|
+
|
|
3
|
+
This project follows the
|
|
4
|
+
[Contributor Covenant, version 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
|
|
5
|
+
|
|
6
|
+
## Our Pledge
|
|
7
|
+
|
|
8
|
+
We as members, contributors, and maintainers pledge to make participation in
|
|
9
|
+
this project a harassment-free experience for everyone, regardless of age,
|
|
10
|
+
body size, visible or invisible disability, ethnicity, sex characteristics,
|
|
11
|
+
gender identity and expression, level of experience, education, socio-economic
|
|
12
|
+
status, nationality, personal appearance, race, religion, or sexual identity
|
|
13
|
+
and orientation. We pledge to act and interact in ways that contribute to an
|
|
14
|
+
open, welcoming, diverse, inclusive, and healthy community.
|
|
15
|
+
|
|
16
|
+
## Our Standards
|
|
17
|
+
|
|
18
|
+
Examples of behavior that contributes to a positive environment include:
|
|
19
|
+
|
|
20
|
+
- Demonstrating empathy and kindness toward other people.
|
|
21
|
+
- Being respectful of differing opinions, viewpoints, and experiences.
|
|
22
|
+
- Giving and gracefully accepting constructive feedback.
|
|
23
|
+
- Accepting responsibility, apologizing to those affected by our mistakes,
|
|
24
|
+
and learning from the experience.
|
|
25
|
+
- Focusing on what is best for the overall community.
|
|
26
|
+
|
|
27
|
+
Examples of unacceptable behavior:
|
|
28
|
+
|
|
29
|
+
- The use of sexualized language or imagery, and sexual attention or advances
|
|
30
|
+
of any kind.
|
|
31
|
+
- Trolling, insulting or derogatory comments, and personal or political
|
|
32
|
+
attacks.
|
|
33
|
+
- Public or private harassment.
|
|
34
|
+
- Publishing others' private information without their explicit permission.
|
|
35
|
+
- Other conduct which could reasonably be considered inappropriate in a
|
|
36
|
+
professional setting.
|
|
37
|
+
|
|
38
|
+
## Enforcement Responsibilities
|
|
39
|
+
|
|
40
|
+
Project maintainers are responsible for clarifying and enforcing our
|
|
41
|
+
standards of acceptable behavior and will take appropriate and fair
|
|
42
|
+
corrective action in response to any behavior that they deem inappropriate,
|
|
43
|
+
threatening, offensive, or harmful.
|
|
44
|
+
|
|
45
|
+
## Enforcement
|
|
46
|
+
|
|
47
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
48
|
+
reported to the project maintainer via the contact method on
|
|
49
|
+
`https://github.com/king-tero`. All complaints will be reviewed and
|
|
50
|
+
investigated promptly and fairly.
|
|
51
|
+
|
|
52
|
+
Community Impact Guidelines:
|
|
53
|
+
<https://www.contributor-covenant.org/version/2/1/code_of_conduct/#enforcement-guidelines>
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in VT Sentinel. This guide covers the basics for
|
|
4
|
+
reporting issues, submitting patches, and building the plugin locally.
|
|
5
|
+
|
|
6
|
+
## Reporting issues
|
|
7
|
+
|
|
8
|
+
- Non-security bugs and feature requests: open a GitHub issue.
|
|
9
|
+
- Security vulnerabilities: see [`SECURITY.md`](./SECURITY.md).
|
|
10
|
+
|
|
11
|
+
When filing a bug, please include:
|
|
12
|
+
|
|
13
|
+
- VT Sentinel version (`openclaw plugins inspect openclaw-plugin-vt-sentinel`).
|
|
14
|
+
- OpenClaw version (`openclaw --version`).
|
|
15
|
+
- OS and Node.js version.
|
|
16
|
+
- The output of `openclaw security audit --deep --json` filtered to
|
|
17
|
+
`vt-sentinel.*` findings, if relevant.
|
|
18
|
+
|
|
19
|
+
## Building locally
|
|
20
|
+
|
|
21
|
+
Requirements: Node.js >= 18, npm, TypeScript.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
git clone https://github.com/king-tero/VT-sentinel.git
|
|
25
|
+
cd VT-sentinel
|
|
26
|
+
npm install
|
|
27
|
+
npm run build
|
|
28
|
+
npm test
|
|
29
|
+
npm run scan
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`npm run scan` runs a local re-implementation of OpenClaw's install-security
|
|
33
|
+
scanner against the compiled `dist/`. A clean baseline is `0 critical, 0 warn`.
|
|
34
|
+
CI blocks on any finding.
|
|
35
|
+
|
|
36
|
+
## Code style
|
|
37
|
+
|
|
38
|
+
- TypeScript `strict`.
|
|
39
|
+
- No inline first-person narrative in comments (use neutral phrasing).
|
|
40
|
+
- No references to coding assistants or editors.
|
|
41
|
+
- Defensive threat-detection regex literals belong in
|
|
42
|
+
`src/signatures/*.json`, not in `.ts` source — so static scanners do not
|
|
43
|
+
mistake detection patterns for malicious code.
|
|
44
|
+
- Prefer host-runtime helpers (`api.runtime.*`) over direct environment
|
|
45
|
+
reads. Any residual `process.env` usage must live in a module with no
|
|
46
|
+
HTTP-client imports, to avoid tripping the install-security scanner's
|
|
47
|
+
env-harvesting rule.
|
|
48
|
+
|
|
49
|
+
## Pull requests
|
|
50
|
+
|
|
51
|
+
- One logical change per PR.
|
|
52
|
+
- Update `CHANGELOG.md` under an `Unreleased` section if the change is user
|
|
53
|
+
visible.
|
|
54
|
+
- `npm test` and `npm run scan` must pass.
|
|
55
|
+
|
|
56
|
+
## Release process (maintainers)
|
|
57
|
+
|
|
58
|
+
1. Bump `version` in `package.json` and `openclaw.plugin.json`.
|
|
59
|
+
2. Add a `CHANGELOG.md` entry.
|
|
60
|
+
3. `npm run build && npm test && npm run scan`.
|
|
61
|
+
4. `npm publish`.
|
|
62
|
+
5. Publish to ClawHub with `--source-commit <new commit SHA> --source-ref vX.Y.Z`.
|
|
63
|
+
6. Tag the release in git: `git tag vX.Y.Z && git push --tags`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 king-tero and VT Sentinel contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -116,7 +116,7 @@ VT Sentinel connects to [VTAI](https://ai.virustotal.com) — VirusTotal's LLM-o
|
|
|
116
116
|
|
|
117
117
|
File analysis includes:
|
|
118
118
|
- **AV detections** from 60+ antivirus engines
|
|
119
|
-
- **AI Code Insight** (
|
|
119
|
+
- **AI Code Insight** (VirusTotal AI-powered semantic analysis)
|
|
120
120
|
- **Crowdsourced AI results** from the VirusTotal community
|
|
121
121
|
|
|
122
122
|
## Privacy & compliance
|
|
@@ -124,7 +124,8 @@ File analysis includes:
|
|
|
124
124
|
VT Sentinel is a security plugin, so transparency about what it reads, writes,
|
|
125
125
|
and sends is part of the threat model. The same structured view is emitted by
|
|
126
126
|
`vt_sentinel_status` (Compliance / Data Flow block) and by `openclaw security
|
|
127
|
-
audit --deep` (via the plugin's `securityAuditCollector` —
|
|
127
|
+
audit --deep` (via the plugin's `securityAuditCollector` — CLI audit support
|
|
128
|
+
since v0.12.1), so
|
|
128
129
|
you can verify the behavior from either surface without reading source.
|
|
129
130
|
|
|
130
131
|
### Data flow
|
|
@@ -155,7 +156,7 @@ supported; the env variable is not.
|
|
|
155
156
|
### Legacy highlights retained from v0.11.0
|
|
156
157
|
|
|
157
158
|
- **Network endpoints:** only `www.virustotal.com` (VT API) and
|
|
158
|
-
`ai.virustotal.com` (VTAI). `registry.npmjs.org` / `clawhub.
|
|
159
|
+
`ai.virustotal.com` (VTAI). `registry.npmjs.org` / `clawhub.ai` are
|
|
159
160
|
contacted only when you explicitly invoke `vt_sentinel_update` — not on
|
|
160
161
|
plugin load.
|
|
161
162
|
- **No environment mutations:** the plugin never writes to `process.env`.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Only the latest `0.12.x` release line receives security fixes. Earlier
|
|
6
|
+
versions are unsupported; upgrade via ClawHub or npm.
|
|
7
|
+
|
|
8
|
+
## Reporting a Vulnerability
|
|
9
|
+
|
|
10
|
+
**Do not open a public issue for security reports.**
|
|
11
|
+
|
|
12
|
+
Please report suspected vulnerabilities by email to the repository owner via
|
|
13
|
+
the GitHub profile contact method (`https://github.com/king-tero`). Include:
|
|
14
|
+
|
|
15
|
+
- A description of the vulnerability and its impact.
|
|
16
|
+
- Reproduction steps or a minimal proof of concept.
|
|
17
|
+
- Affected version(s).
|
|
18
|
+
- Your preferred disclosure timeline, if any.
|
|
19
|
+
|
|
20
|
+
You should receive an acknowledgement within 7 days. We aim to ship a fix
|
|
21
|
+
and a coordinated advisory within 30 days for high-severity issues, faster
|
|
22
|
+
when impact warrants it.
|
|
23
|
+
|
|
24
|
+
## Scope
|
|
25
|
+
|
|
26
|
+
In scope:
|
|
27
|
+
|
|
28
|
+
- The plugin itself (`src/**`, `dist/**`).
|
|
29
|
+
- The installer skill (`vt-sentinel-installer`).
|
|
30
|
+
- Interactions with `virustotal.com` and `ai.virustotal.com` endpoints.
|
|
31
|
+
|
|
32
|
+
Out of scope:
|
|
33
|
+
|
|
34
|
+
- Vulnerabilities in upstream VirusTotal services (report to VirusTotal).
|
|
35
|
+
- Vulnerabilities in OpenClaw itself (report to the OpenClaw project).
|
|
36
|
+
- Social engineering or physical attacks.
|
|
37
|
+
|
|
38
|
+
## Non-Vulnerabilities
|
|
39
|
+
|
|
40
|
+
The following behaviors are intentional and not security issues:
|
|
41
|
+
|
|
42
|
+
- Outbound HTTPS requests to `www.virustotal.com` / `ai.virustotal.com`.
|
|
43
|
+
- Reading files under configured watch directories to classify and hash them.
|
|
44
|
+
- Uploading files when consent has been granted (per the configured
|
|
45
|
+
`sensitiveFilePolicy` / `semanticFilePolicy`).
|
|
46
|
+
- Storing a VTAI agent token on disk under `$OPENCLAW_STATE_DIR` with
|
|
47
|
+
mode `0o600`.
|
|
48
|
+
|
|
49
|
+
## Hardening notes
|
|
50
|
+
|
|
51
|
+
- Audit logs are created under `$OPENCLAW_STATE_DIR/vt-sentinel-audit/`
|
|
52
|
+
with the directory set to mode `0o700` and individual log files to `0o600`.
|
|
53
|
+
- The plugin does not mutate `process.env`.
|
|
54
|
+
- Threat-detection signatures live in JSON so that static scanners do not
|
|
55
|
+
confuse defensive patterns with malicious code.
|
|
56
|
+
- Run `openclaw security audit --deep --json` to inspect what the plugin
|
|
57
|
+
reads, writes, and sends. A structured "compliance snapshot" is emitted.
|
package/dist/classifier.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export declare class FileClassifier {
|
|
|
39
39
|
/**
|
|
40
40
|
* Peek inside a ZIP file by reading its local file headers.
|
|
41
41
|
* ZIP local file header: PK\x03\x04 ... filename at offset 30.
|
|
42
|
-
*
|
|
42
|
+
* Reads enough bytes to scan the first ~50 entries without full decompression.
|
|
43
43
|
*
|
|
44
44
|
* Returns: 'skill' | 'executable' | 'office' | 'archive'
|
|
45
45
|
*/
|
package/dist/classifier.js
CHANGED
|
@@ -106,7 +106,7 @@ class FileClassifier {
|
|
|
106
106
|
/**
|
|
107
107
|
* Peek inside a ZIP file by reading its local file headers.
|
|
108
108
|
* ZIP local file header: PK\x03\x04 ... filename at offset 30.
|
|
109
|
-
*
|
|
109
|
+
* Reads enough bytes to scan the first ~50 entries without full decompression.
|
|
110
110
|
*
|
|
111
111
|
* Returns: 'skill' | 'executable' | 'office' | 'archive'
|
|
112
112
|
*/
|
|
@@ -113,8 +113,8 @@ function isBroadWatchDir(dir) {
|
|
|
113
113
|
// Unix near-root
|
|
114
114
|
if (['/home', '/Users'].includes(norm))
|
|
115
115
|
return true;
|
|
116
|
-
// Exact $HOME (common mistake — scans user profile including dotfiles)
|
|
117
|
-
//
|
|
116
|
+
// Exact $HOME (common mistake — scans user profile including dotfiles).
|
|
117
|
+
// $HOME cannot be resolved here without I/O; instead treat paths that end
|
|
118
118
|
// with just the user directory segment as broad.
|
|
119
119
|
// Heuristic: directory depth 2 or less (e.g. /Users/foo, /home/foo, /root).
|
|
120
120
|
const parts = norm.split(/[\\/]/).filter(Boolean);
|
|
@@ -336,7 +336,7 @@ function buildComplianceSnapshot(input) {
|
|
|
336
336
|
// same snapshot as the gateway-side collector, but exclusively from the
|
|
337
337
|
// audit context (ctx.config, ctx.stateDir, ctx.configPath) — no closure
|
|
338
338
|
// state, no cross-module shared variables. Everything is reconstructable
|
|
339
|
-
// from
|
|
339
|
+
// from the context the CLI provides.
|
|
340
340
|
//
|
|
341
341
|
// Differences from the gateway-side invocation:
|
|
342
342
|
// - `watchDirs` only includes user-configured dirs (`cfg.watchDirs`); the
|
package/dist/env-access.d.ts
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* profile name, used to derive auxiliary watch-dir paths).
|
|
5
5
|
*
|
|
6
6
|
* Kept in a separate file with zero network-related identifiers so the
|
|
7
|
-
* install-security scanner's env-harvesting rule cannot trigger here.
|
|
8
|
-
* memory/install-scanner-2026.4.5.md for the rule details.
|
|
7
|
+
* install-security scanner's env-harvesting rule cannot trigger here.
|
|
9
8
|
*/
|
|
10
9
|
/**
|
|
11
10
|
* Return the active OpenClaw profile name (without the `.openclaw-` prefix),
|
package/dist/env-access.js
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* profile name, used to derive auxiliary watch-dir paths).
|
|
6
6
|
*
|
|
7
7
|
* Kept in a separate file with zero network-related identifiers so the
|
|
8
|
-
* install-security scanner's env-harvesting rule cannot trigger here.
|
|
9
|
-
* memory/install-scanner-2026.4.5.md for the rule details.
|
|
8
|
+
* install-security scanner's env-harvesting rule cannot trigger here.
|
|
10
9
|
*/
|
|
11
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
11
|
exports.getActiveProfile = getActiveProfile;
|
package/dist/index.js
CHANGED
|
@@ -121,7 +121,7 @@ async function fetchLatestVersion() {
|
|
|
121
121
|
catch { }
|
|
122
122
|
return null;
|
|
123
123
|
}
|
|
124
|
-
// --- Self-exclusion: never scan
|
|
124
|
+
// --- Self-exclusion: never scan or quarantine the plugin's own files ---
|
|
125
125
|
// __dirname = dist/ inside the installed plugin directory.
|
|
126
126
|
// Resolve symlinks to prevent bypass via symlinked extensions dir.
|
|
127
127
|
const SELF_DIR = (() => {
|
|
@@ -173,9 +173,9 @@ function vtSentinelPlugin(api) {
|
|
|
173
173
|
let latestKnownVersion = null;
|
|
174
174
|
let updateCheckFailed = false;
|
|
175
175
|
// State directory: resolved once via the host runtime helper (which itself
|
|
176
|
-
// honors OPENCLAW_STATE_DIR, legacy paths, and profile overrides).
|
|
177
|
-
//
|
|
178
|
-
// co-occur with the axios calls elsewhere in this
|
|
176
|
+
// honors OPENCLAW_STATE_DIR, legacy paths, and profile overrides). This
|
|
177
|
+
// module never reads environment variables directly — doing so would
|
|
178
|
+
// co-occur with the axios calls elsewhere in this file and trip the
|
|
179
179
|
// install-security scanner's env-harvesting rule.
|
|
180
180
|
const resolvedStateDir = (() => {
|
|
181
181
|
const fromRuntime = api.runtime?.state?.resolveStateDir;
|
|
@@ -774,7 +774,7 @@ function vtSentinelPlugin(api) {
|
|
|
774
774
|
credentialMode === 'vtai' ? 'vtai' : 'none';
|
|
775
775
|
const eff = configManager.getEffective();
|
|
776
776
|
// Use the audit context's stateDir when provided (it already
|
|
777
|
-
// honors profile overrides); fall back to
|
|
777
|
+
// honors profile overrides); fall back to the resolved one.
|
|
778
778
|
const sd = ctx.stateDir || resolvedStateDir;
|
|
779
779
|
const logModes = (0, compliance_snapshot_1.collectLogModes)(sd);
|
|
780
780
|
const snap = (0, compliance_snapshot_1.buildComplianceSnapshot)({
|
|
@@ -946,7 +946,7 @@ function vtSentinelPlugin(api) {
|
|
|
946
946
|
return false;
|
|
947
947
|
}
|
|
948
948
|
}));
|
|
949
|
-
// Diff against
|
|
949
|
+
// Diff against the tracked watchRoots set, not chokidar's getWatched()
|
|
950
950
|
for (const dir of watchRoots) {
|
|
951
951
|
if (!desiredSet.has(dir)) {
|
|
952
952
|
watcher.unwatch(dir);
|
|
@@ -1495,7 +1495,7 @@ function vtSentinelPlugin(api) {
|
|
|
1495
1495
|
// Layer 1.5: TOCTOU detection — block download+execute of same file in one command.
|
|
1496
1496
|
// If a command downloads AND executes the same file, scanning can't happen between them.
|
|
1497
1497
|
// Note: extractFromCommand deduplicates by path, so the same path can't appear as both
|
|
1498
|
-
// download_target and exec_target.
|
|
1498
|
+
// download_target and exec_target. Exec context is checked independently via regex.
|
|
1499
1499
|
const cmdParts = (0, path_extractor_1.extractFromCommand)(command);
|
|
1500
1500
|
const writeTargets = new Set(cmdParts
|
|
1501
1501
|
.filter(p => p.source === 'download_target' || p.source === 'redirect_target')
|
package/dist/path-extractor.js
CHANGED
|
@@ -130,7 +130,7 @@ const REDIRECT_PATTERNS = [
|
|
|
130
130
|
/\|\s*Out-File\s+(?:-FilePath\s+)?["']?(\S+?)["']?(?:\s|$)/i,
|
|
131
131
|
/\|\s*Set-Content\s+(?:-Path\s+)?["']?(\S+?)["']?(?:\s|$)/i,
|
|
132
132
|
];
|
|
133
|
-
// Script execution targets — the scripts themselves are what
|
|
133
|
+
// Script execution targets — the scripts themselves are what the scanner should evaluate.
|
|
134
134
|
const EXEC_PATTERNS = [
|
|
135
135
|
// Unix — shells and interpreters (dash = default /bin/sh on Debian/Ubuntu)
|
|
136
136
|
/(?:bash|sh|zsh|dash|python3?|ruby|perl|node|pwsh|php)\s+["']?(\S+?)["']?(?:\s|$)/,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_comment": "Threat-detection regex signatures for VT Sentinel's path-extractor. Kept in JSON so the install-security scanner (which only walks .js/.ts/etc.) never sees literal trigger strings like 'child_process' or 'fetch' that live inside
|
|
2
|
+
"_comment": "Threat-detection regex signatures for VT Sentinel's path-extractor. Kept in JSON so the install-security scanner (which only walks .js/.ts/etc.) never sees literal trigger strings like 'child_process' or 'fetch' that live inside the defensive patterns. Loaded at module init in path-extractor.ts.",
|
|
3
3
|
"pipeExec": [
|
|
4
4
|
{ "pattern": "curl\\s+[^|]*\\|\\s*(?:sudo\\s+)?(?:bash|sh|zsh|dash)\\b", "description": "curl piped to shell" },
|
|
5
5
|
{ "pattern": "curl\\s+[^|]*\\|\\s*(?:sudo\\s+)?(?:python3?|ruby|perl|node|php|deno|bun)\\b", "description": "curl piped to interpreter" },
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "openclaw-plugin-vt-sentinel",
|
|
3
3
|
"name": "VT Sentinel",
|
|
4
4
|
"description": "VirusTotal Sentinel for OpenClaw — malware detection, active protection, and AI-powered code analysis.",
|
|
5
|
-
"version": "0.12.
|
|
5
|
+
"version": "0.12.3",
|
|
6
6
|
"skills": ["./skills"],
|
|
7
7
|
"contracts": {
|
|
8
8
|
"tools": [
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-plugin-vt-sentinel",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.3",
|
|
4
4
|
"displayName": "VT Sentinel",
|
|
5
|
-
"description": "VirusTotal Sentinel for OpenClaw
|
|
5
|
+
"description": "VirusTotal Sentinel for OpenClaw — malware detection, active protection, and AI-powered code analysis for OpenClaw agents.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
-
"
|
|
8
|
+
"author": "king-tero",
|
|
9
|
+
"homepage": "https://github.com/king-tero/VT-sentinel#readme",
|
|
9
10
|
"repository": {
|
|
10
11
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/king-tero/VT-sentinel"
|
|
12
|
+
"url": "git+https://github.com/king-tero/VT-sentinel.git"
|
|
12
13
|
},
|
|
13
14
|
"bugs": {
|
|
14
15
|
"url": "https://github.com/king-tero/VT-sentinel/issues"
|
|
@@ -37,6 +38,9 @@
|
|
|
37
38
|
"files": [
|
|
38
39
|
"README.md",
|
|
39
40
|
"CHANGELOG.md",
|
|
41
|
+
"SECURITY.md",
|
|
42
|
+
"CONTRIBUTING.md",
|
|
43
|
+
"CODE_OF_CONDUCT.md",
|
|
40
44
|
"dist/index.*",
|
|
41
45
|
"dist/scanner.*",
|
|
42
46
|
"dist/vt-api.*",
|
|
@@ -57,7 +61,9 @@
|
|
|
57
61
|
"openclaw.plugin.json"
|
|
58
62
|
],
|
|
59
63
|
"openclaw": {
|
|
60
|
-
"extensions": [
|
|
64
|
+
"extensions": [
|
|
65
|
+
"./dist/index.js"
|
|
66
|
+
],
|
|
61
67
|
"install": {
|
|
62
68
|
"minHostVersion": ">=2026.3.22"
|
|
63
69
|
},
|
|
@@ -66,16 +72,19 @@
|
|
|
66
72
|
"minGatewayVersion": ">=2026.3.22"
|
|
67
73
|
},
|
|
68
74
|
"build": {
|
|
69
|
-
"openclawVersion": "2026.4.
|
|
75
|
+
"openclawVersion": "2026.4.12"
|
|
70
76
|
}
|
|
71
77
|
},
|
|
72
78
|
"dependencies": {
|
|
73
|
-
"axios": "^1.
|
|
79
|
+
"axios": "^1.15.0",
|
|
74
80
|
"chokidar": "^3.5.3",
|
|
75
|
-
"form-data": "^4.0.
|
|
81
|
+
"form-data": "^4.0.5"
|
|
76
82
|
},
|
|
77
83
|
"devDependencies": {
|
|
78
84
|
"@types/node": "^20.0.0",
|
|
79
|
-
"typescript": "^
|
|
85
|
+
"typescript": "^6.0.2"
|
|
86
|
+
},
|
|
87
|
+
"engines": {
|
|
88
|
+
"node": ">=18"
|
|
80
89
|
}
|
|
81
90
|
}
|
|
@@ -16,7 +16,7 @@ metadata:
|
|
|
16
16
|
Protects OpenClaw users with **active prevention**, not just detection:
|
|
17
17
|
|
|
18
18
|
1. **Antivirus engines** — 60+ vendors check file hashes for known malware
|
|
19
|
-
2. **AI Code Insight** —
|
|
19
|
+
2. **AI Code Insight** — VirusTotal AI-powered semantic analysis for scripts, skills, binaries
|
|
20
20
|
3. **Active blocking** — Files detected as malicious are blocklisted and quarantined. Any subsequent attempt to execute them is automatically blocked before it runs.
|
|
21
21
|
|
|
22
22
|
Both AV and AI sources are always checked. The final verdict is the worst of the two. Malicious files are quarantined (renamed to `.QUARANTINED`) and added to a runtime blocklist that prevents their execution via `exec` or `bash` tools.
|