Agent Updates
This commit is contained in:
@@ -1,23 +1,27 @@
|
||||
/** Shared helpers for /bin/agent tools (preamble for agent bundle). */
|
||||
|
||||
/**
|
||||
* Paths allowed for rename/delete via agent tools (stricter than general read paths).
|
||||
* @param {string} absPath
|
||||
* @returns {boolean}
|
||||
* Read-only base system (kernel / system Hyperdrive + virtual fs).
|
||||
* Everything else is writable by default (denylist, not allowlist).
|
||||
* @type {readonly string[]}
|
||||
*/
|
||||
function bareAgentPathAllowedMutate(absPath) {
|
||||
const p = String(absPath || '').replace(/\\/g, '/')
|
||||
if (!p.startsWith('/') || p.includes('..')) return false
|
||||
return (
|
||||
p.startsWith('/home/') ||
|
||||
p.startsWith('/tmp/') ||
|
||||
p === '/tmp' ||
|
||||
p.startsWith('/root/') ||
|
||||
p.startsWith('/mnt/')
|
||||
)
|
||||
}
|
||||
var BARE_AGENT_MUTATE_DENY_PREFIXES = Object.freeze([
|
||||
'/bin',
|
||||
'/etc',
|
||||
'/boot',
|
||||
'/lib',
|
||||
'/usr',
|
||||
'/share',
|
||||
'/proc',
|
||||
'/dev',
|
||||
'/sys',
|
||||
'/run'
|
||||
])
|
||||
|
||||
/** @type {readonly string[]} */
|
||||
/**
|
||||
* Seed list for diagnostic snapshots. Live reads allow any /proc path.
|
||||
* @type {readonly string[]}
|
||||
*/
|
||||
var BARE_AGENT_PROC_READ_ALLOWLIST = Object.freeze([
|
||||
'/proc/bare_os/metrics_live.json',
|
||||
'/proc/bare_os/features',
|
||||
@@ -34,6 +38,56 @@ var BARE_AGENT_PROC_READ_ALLOWLIST = Object.freeze([
|
||||
'/proc/bare_os/swarm_status.json'
|
||||
])
|
||||
|
||||
/**
|
||||
* @param {string} absPath
|
||||
* @returns {string}
|
||||
*/
|
||||
function bareAgentNormalizeAbsPath(absPath) {
|
||||
const p = String(absPath || '').replace(/\\/g, '/')
|
||||
if (!p.startsWith('/') || p.includes('..')) return ''
|
||||
if (p.length > 1) return p.replace(/\/+$/, '')
|
||||
return p
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} absPath
|
||||
* @param {unknown} prefixes
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function bareAgentPrefixDenied(absPath, prefixes) {
|
||||
const p = bareAgentNormalizeAbsPath(absPath)
|
||||
if (!p) return true
|
||||
const list =
|
||||
Array.isArray(prefixes) && prefixes.length
|
||||
? prefixes
|
||||
: BARE_AGENT_MUTATE_DENY_PREFIXES
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const pref = String(list[i] || '').replace(/\/+$/, '')
|
||||
if (!pref) continue
|
||||
if (p === pref || p.startsWith(pref + '/')) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Any absolute guest path is readable (denylist-empty).
|
||||
* @param {string} absPath
|
||||
*/
|
||||
function bareAgentPathAllowedRead(absPath) {
|
||||
return Boolean(bareAgentNormalizeAbsPath(absPath))
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes/renames/deletes: whole VFS except the read-only base system.
|
||||
* @param {string} absPath
|
||||
* @param {unknown} [prefixes]
|
||||
*/
|
||||
function bareAgentPathAllowedMutate(absPath, prefixes) {
|
||||
const p = bareAgentNormalizeAbsPath(absPath)
|
||||
if (!p || p === '/') return false
|
||||
return !bareAgentPrefixDenied(p, prefixes)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} statObj
|
||||
* @param {string} path
|
||||
@@ -231,10 +285,6 @@ function bareAgentManResolvePage(db, topic, sectionExplicit) {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function bareAgentProcReadPathAllowed(absPath) {
|
||||
const p = String(absPath || '').replace(/\\/g, '/')
|
||||
if (!p.startsWith('/') || p.includes('..')) return false
|
||||
for (let i = 0; i < BARE_AGENT_PROC_READ_ALLOWLIST.length; i++) {
|
||||
if (p === BARE_AGENT_PROC_READ_ALLOWLIST[i]) return true
|
||||
}
|
||||
return false
|
||||
const p = bareAgentNormalizeAbsPath(absPath)
|
||||
return Boolean(p && (p === '/proc' || p.startsWith('/proc/')))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user