@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)() ?? undefined,
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;
@@ -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 version = output.includes('/') ? output.split('/').pop() : output;
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
- _cachedOpenClawVersion = v;
89
- return _cachedOpenClawVersion;
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 ?? (_source?.ip_addresses[0] ?? null);
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) => {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "id": "shield",
3
3
  "name": "OpenClaw Shield",
4
- "description": "Real-time security monitoring streams enriched, redacted security events to the Shield detection platform.",
5
- "version": "0.6.1",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upx-us/shield",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Security monitoring plugin for OpenClaw agents — streams enriched security events to the Shield detection platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",