@remcp/runtime 0.2.207 → 0.2.209
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/package.json +1 -1
- package/src/privilege-boundary.mjs +59 -0
- package/src/tools/stats.mjs +2 -0
package/package.json
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
|
|
5
|
+
// Read-only capability evidence. God Mode does not change operating-system identity.
|
|
6
|
+
// Never execute sudo or attempt privilege escalation while gathering diagnostics.
|
|
7
|
+
export function privilegeBoundary({
|
|
8
|
+
platform = process.platform,
|
|
9
|
+
effectiveUid = typeof process.geteuid === 'function' ? process.geteuid() : null,
|
|
10
|
+
procStatus,
|
|
11
|
+
windowsGroupOutput,
|
|
12
|
+
} = {}) {
|
|
13
|
+
if (platform === 'win32') {
|
|
14
|
+
let output = windowsGroupOutput;
|
|
15
|
+
if (output === undefined) {
|
|
16
|
+
try {
|
|
17
|
+
const result = spawnSync('whoami.exe', ['/groups'], {
|
|
18
|
+
encoding: 'utf8', windowsHide: true, timeout: 3000, maxBuffer: 64 * 1024,
|
|
19
|
+
});
|
|
20
|
+
output = result.status === 0 && !result.error ? result.stdout : '';
|
|
21
|
+
} catch { output = ''; }
|
|
22
|
+
}
|
|
23
|
+
const sid = String(output).match(/S-1-16-(?:4096|8192|12288|16384|20480)\b/g)?.at(-1) || null;
|
|
24
|
+
const integrityLevel = sid === 'S-1-16-16384' ? 'system'
|
|
25
|
+
: sid === 'S-1-16-12288' ? 'high'
|
|
26
|
+
: sid === 'S-1-16-8192' ? 'medium'
|
|
27
|
+
: sid === 'S-1-16-4096' ? 'low'
|
|
28
|
+
: sid === 'S-1-16-20480' ? 'protected_process' : 'unknown';
|
|
29
|
+
return {
|
|
30
|
+
platform,
|
|
31
|
+
integrityLevel,
|
|
32
|
+
elevation: integrityLevel === 'high' || integrityLevel === 'system'
|
|
33
|
+
? 'elevated_token' : integrityLevel === 'unknown' ? 'unknown' : 'not_elevated',
|
|
34
|
+
note: 'Windows integrity is read from the running token, not inferred from scheduled-task settings. A high-integrity token is not proof of unrestricted OS access. UAC and ACLs still apply.',
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (platform === 'darwin') {
|
|
38
|
+
return { platform, effectiveUid, elevation: effectiveUid === 0 ? 'already_root' : 'requires_os_authorization', note: 'macOS sudo, Full Disk Access, Accessibility and Automation are separate OS permissions.' };
|
|
39
|
+
}
|
|
40
|
+
if (platform !== 'linux') return { platform, elevation: 'unknown' };
|
|
41
|
+
let status = procStatus;
|
|
42
|
+
if (status === undefined) {
|
|
43
|
+
try { status = readFileSync('/proc/self/status', 'utf8'); } catch { status = ''; }
|
|
44
|
+
}
|
|
45
|
+
const match = /^NoNewPrivs:[ \t]*([01])[ \t]*$/m.exec(status);
|
|
46
|
+
const noNewPrivileges = match ? match[1] === '1' : null;
|
|
47
|
+
const elevation = effectiveUid === 0 ? 'already_root'
|
|
48
|
+
: noNewPrivileges === true ? 'blocked_by_no_new_privileges'
|
|
49
|
+
: noNewPrivileges === false ? 'requires_os_authorization' : 'unknown';
|
|
50
|
+
return {
|
|
51
|
+
platform,
|
|
52
|
+
effectiveUid,
|
|
53
|
+
noNewPrivileges,
|
|
54
|
+
elevation,
|
|
55
|
+
note: elevation === 'blocked_by_no_new_privileges'
|
|
56
|
+
? 'The service process cannot gain privileges through sudo/setuid until restarted with an appropriate OS policy. God Mode does not override this.'
|
|
57
|
+
: 'The OS still controls sudo/polkit and privilege grants. God Mode alone does not grant root.',
|
|
58
|
+
};
|
|
59
|
+
}
|
package/src/tools/stats.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { dangerousPatternIds } from '../policy.mjs';
|
|
|
4
4
|
import { listProcessSessions, listSearchSessions } from '../sessions.mjs';
|
|
5
5
|
import { telemetryStatus } from '../telemetry.mjs';
|
|
6
6
|
import { VERSION } from '../version.mjs';
|
|
7
|
+
import { privilegeBoundary } from '../privilege-boundary.mjs';
|
|
7
8
|
import { text } from '../util.mjs';
|
|
8
9
|
|
|
9
10
|
// Read-only introspection. Mutating configuration is a separate, deliberately narrow tool:
|
|
@@ -14,6 +15,7 @@ export async function getRuntimeInfoTool() {
|
|
|
14
15
|
return text(JSON.stringify({
|
|
15
16
|
version: VERSION,
|
|
16
17
|
runtime: describeConfig(),
|
|
18
|
+
osPrivilegeBoundary: privilegeBoundary(),
|
|
17
19
|
policy: {
|
|
18
20
|
// Reported first because it changes how everything below should be read.
|
|
19
21
|
unrestricted: runtimeConfig.unrestricted,
|