@upx-us/shield 0.6.1 → 0.6.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
CHANGED
|
@@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.6.3] — 2026-03-09
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **Version normalization** — `resolveOpenClawVersion()` now normalizes messy version strings from `openclaw --version` output and the `lastTouchedVersion` config field (e.g. `"OpenClaw 2026.3.8 (3caab92)"` → `"2026.3.8"`). Previously these strings caused false "out of date" alerts on the Shield dashboard.
|
|
11
|
+
- **Missing Network info** — `PUT /v1/instance` now always includes `public_ip` in the machine payload, even when the IP hasn't been resolved yet (sends `""` instead of omitting the field). This ensures the platform can attempt server-side geo-enrichment (Provider/Location) instead of silently skipping it.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- `normalizeSoftwareVersion(v: string): string` — exported helper that applies the full version normalization pipeline (strip `"OpenClaw "` prefix, parenthetical hash, leading `"v"`). Used internally by `resolveOpenClawVersion()` for all auto-detected version paths.
|
|
15
|
+
- `isPrivateIp(ip: string): boolean` — exported helper that detects RFC-1918/loopback addresses. Used by the ingest service to identify when an agent behind NAT (macOS, home/office Linux) self-reports a LAN IP and override it with the authoritative request IP. Ensures correct Network info (Provider, Location) on the Shield dashboard for all platforms.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## [0.6.2] — 2026-03-09
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- **ANSI field prefix bug** — `ansi_content_detected` and `ansi_sequences` were emitted without the `openclaw.` namespace prefix in `tool-result/enrich.ts`. YARAL rules reference them as `additional.fields["openclaw.ansi_content_detected"]` and `additional.fields["openclaw.ansi_sequences"]`. Fields now correctly namespaced. Unblocks `openclaw_ansi_injection` detection rule.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
7
26
|
## [0.6.1] — 2026-03-09
|
|
8
27
|
|
|
9
28
|
### Fixed
|
|
@@ -17,8 +17,8 @@ function buildToolResult(raw, ctx) {
|
|
|
17
17
|
};
|
|
18
18
|
const ansiMatches = resultText.match(/\x1b\[[0-9;]*[a-zA-Z]|\x1b\]|\x07|\x1b\(B/g);
|
|
19
19
|
if (ansiMatches && ansiMatches.length > 0) {
|
|
20
|
-
meta['ansi_content_detected'] = 'true';
|
|
21
|
-
meta['ansi_sequences'] = ansiMatches.slice(0, 10).map((s) => s.replace(/\x1b/g, 'ESC')).join(', ');
|
|
20
|
+
meta['openclaw.ansi_content_detected'] = 'true';
|
|
21
|
+
meta['openclaw.ansi_sequences'] = ansiMatches.slice(0, 10).map((s) => s.replace(/\x1b/g, 'ESC')).join(', ');
|
|
22
22
|
}
|
|
23
23
|
const event = {
|
|
24
24
|
timestamp: ctx.timestamp,
|
package/dist/src/index.js
CHANGED
|
@@ -104,7 +104,7 @@ async function poll() {
|
|
|
104
104
|
os: process.platform,
|
|
105
105
|
arch: process.arch,
|
|
106
106
|
node_version: process.version,
|
|
107
|
-
public_ip: (0, transformer_1.getCachedPublicIp)() ??
|
|
107
|
+
public_ip: (0, transformer_1.getCachedPublicIp)() ?? '',
|
|
108
108
|
},
|
|
109
109
|
software: {
|
|
110
110
|
plugin_version: version_1.VERSION,
|
|
@@ -118,6 +118,9 @@ async function poll() {
|
|
|
118
118
|
}),
|
|
119
119
|
},
|
|
120
120
|
};
|
|
121
|
+
if (!(0, transformer_1.getCachedPublicIp)()) {
|
|
122
|
+
log.warn('bridge', 'Public IP not yet resolved — sending empty public_ip so platform can enrich server-side');
|
|
123
|
+
}
|
|
121
124
|
const result = await (0, sender_1.reportInstance)(instancePayload, config.credentials);
|
|
122
125
|
log.info('bridge', `Instance report → Platform: success=${result.ok}`);
|
|
123
126
|
if (result.ok) {
|
|
@@ -8,10 +8,12 @@ export interface EnvelopeEvent {
|
|
|
8
8
|
export interface IngestPayload {
|
|
9
9
|
entries: EnvelopeEvent[];
|
|
10
10
|
}
|
|
11
|
+
export declare function normalizeSoftwareVersion(v: string): string;
|
|
11
12
|
export declare function resolveOpenClawVersion(): string;
|
|
12
13
|
export declare function _resetCachedOpenClawVersion(): void;
|
|
13
14
|
export declare function resolveAgentLabel(agentId: string): string;
|
|
14
15
|
export declare function getCachedPublicIp(): string | null;
|
|
16
|
+
export declare function isPrivateIp(ip: string): boolean;
|
|
15
17
|
export declare function resolveOutboundIp(): Promise<string | null>;
|
|
16
18
|
export declare function transformEntries(entries: RawEntry[]): EnvelopeEvent[];
|
|
17
19
|
export declare function generateHostTelemetry(): EnvelopeEvent | null;
|
package/dist/src/transformer.js
CHANGED
|
@@ -33,10 +33,12 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.normalizeSoftwareVersion = normalizeSoftwareVersion;
|
|
36
37
|
exports.resolveOpenClawVersion = resolveOpenClawVersion;
|
|
37
38
|
exports._resetCachedOpenClawVersion = _resetCachedOpenClawVersion;
|
|
38
39
|
exports.resolveAgentLabel = resolveAgentLabel;
|
|
39
40
|
exports.getCachedPublicIp = getCachedPublicIp;
|
|
41
|
+
exports.isPrivateIp = isPrivateIp;
|
|
40
42
|
exports.resolveOutboundIp = resolveOutboundIp;
|
|
41
43
|
exports.transformEntries = transformEntries;
|
|
42
44
|
exports.generateHostTelemetry = generateHostTelemetry;
|
|
@@ -51,6 +53,13 @@ const version_1 = require("./version");
|
|
|
51
53
|
const counters_1 = require("./counters");
|
|
52
54
|
const inventory_1 = require("./inventory");
|
|
53
55
|
let _cachedOpenClawVersion = "";
|
|
56
|
+
function normalizeSoftwareVersion(v) {
|
|
57
|
+
return v
|
|
58
|
+
.replace(/^openclaw\s+/i, '')
|
|
59
|
+
.replace(/\s*\([^)]*\)/g, '')
|
|
60
|
+
.replace(/^v/, '')
|
|
61
|
+
.trim();
|
|
62
|
+
}
|
|
54
63
|
function resolveOpenClawVersion() {
|
|
55
64
|
if (_cachedOpenClawVersion !== "")
|
|
56
65
|
return _cachedOpenClawVersion;
|
|
@@ -62,7 +71,7 @@ function resolveOpenClawVersion() {
|
|
|
62
71
|
const pkgPath = require.resolve('openclaw/package.json');
|
|
63
72
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
64
73
|
if (pkg.version) {
|
|
65
|
-
_cachedOpenClawVersion = pkg.version;
|
|
74
|
+
_cachedOpenClawVersion = normalizeSoftwareVersion(pkg.version);
|
|
66
75
|
return _cachedOpenClawVersion;
|
|
67
76
|
}
|
|
68
77
|
}
|
|
@@ -74,7 +83,8 @@ function resolveOpenClawVersion() {
|
|
|
74
83
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
75
84
|
encoding: 'utf8',
|
|
76
85
|
}).trim();
|
|
77
|
-
const
|
|
86
|
+
const raw = output.includes('/') ? output.split('/').pop() : output;
|
|
87
|
+
const version = normalizeSoftwareVersion(raw);
|
|
78
88
|
if (version && version !== 'unknown') {
|
|
79
89
|
_cachedOpenClawVersion = version;
|
|
80
90
|
return _cachedOpenClawVersion;
|
|
@@ -85,8 +95,11 @@ function resolveOpenClawVersion() {
|
|
|
85
95
|
const cfg = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.openclaw/openclaw.json'), 'utf8'));
|
|
86
96
|
const v = cfg?.meta?.lastTouchedVersion;
|
|
87
97
|
if (v) {
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
const normalized = normalizeSoftwareVersion(v);
|
|
99
|
+
if (normalized) {
|
|
100
|
+
_cachedOpenClawVersion = normalized;
|
|
101
|
+
return _cachedOpenClawVersion;
|
|
102
|
+
}
|
|
90
103
|
}
|
|
91
104
|
}
|
|
92
105
|
catch { }
|
|
@@ -141,7 +154,15 @@ function writeIpCache(ip) {
|
|
|
141
154
|
catch { }
|
|
142
155
|
}
|
|
143
156
|
function getCachedPublicIp() {
|
|
144
|
-
return readIpCache()?.ip ??
|
|
157
|
+
return readIpCache()?.ip ?? null;
|
|
158
|
+
}
|
|
159
|
+
function isPrivateIp(ip) {
|
|
160
|
+
return /^10\./.test(ip) ||
|
|
161
|
+
/^172\.(1[6-9]|2[0-9]|3[01])\./.test(ip) ||
|
|
162
|
+
/^192\.168\./.test(ip) ||
|
|
163
|
+
/^127\./.test(ip) ||
|
|
164
|
+
/^::1$/.test(ip) ||
|
|
165
|
+
/^fd/i.test(ip);
|
|
145
166
|
}
|
|
146
167
|
function resolveOutboundIp() {
|
|
147
168
|
return new Promise((resolve) => {
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "shield",
|
|
3
3
|
"name": "OpenClaw Shield",
|
|
4
|
-
"description": "Real-time security monitoring
|
|
5
|
-
"version": "0.6.
|
|
4
|
+
"description": "Real-time security monitoring \u2014 streams enriched, redacted security events to the Shield detection platform.",
|
|
5
|
+
"version": "0.6.3",
|
|
6
6
|
"skills": [
|
|
7
7
|
"./skills"
|
|
8
8
|
],
|
|
@@ -81,4 +81,4 @@
|
|
|
81
81
|
"skillVersion": "1.0.2",
|
|
82
82
|
"note": "ClawHub auto-increments on publish. Update this after each clawhub submission."
|
|
83
83
|
}
|
|
84
|
-
}
|
|
84
|
+
}
|
package/package.json
CHANGED