T06 · System Persistence
- Location
lib/cron.mjs:115- Finding
Optional Scheduler Installation Creates Cross-Session Persistence
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a coherent Hermes security-monitoring skill, but it needs review because it can install recurring user crontab jobs and can make an unsigned advisory-feed bypass persist.
Install only from a pinned or signed release path, review the generated cron block before using `--apply`, avoid scheduling `--allow-unsigned`, and verify `$HERMES_HOME`, watch paths, feed URLs, and skill-directory permissions before enabling recurring jobs.
lib/cron.mjs:115Optional Scheduler Installation Creates Cross-Session Persistence
SKILL.md:18Unpinned npx Installer Introduces Supply-Chain Execution Risk
scripts/setup_advisory_check_cron.mjs:48Unsigned Advisory Feed Bypass Can Be Installed as a Persistent Scheduled Policy
lib/attestation.mjs:7Generated Attestations Record an Incorrect Skill Version
Referenced artifact was not completely inspected
For standalone installs, verify the signed release manifest before trusting `SKILL.md`, `skill.json`, or the archive. The `skill.json` file is the package metad
Referenced artifact was not completely inspected
For standalone installs, verify the signed release manifest before trusting `SKILL.md`, `skill.json`, or the archive. The `skill.json` file is the package metad
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
RELEASE_PUBKEY_SHA256="711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8"
curl -fsSL "$BASE/checksums.json" -o "$TMP_DIR/checksums.json"
curl -fsSL "$BASE/checksums.sig" -o "$TMP_DIR/checksums.sig"
curl -fsSL "$BASE/signing-public.pem" -o "$TMP_DIR/signing-public.pem"
curl -fsSL "$BASE/$ZIP_NAME" -o "$TMP_DIR/$ZIP_NAME"
Referenced artifact was not completely inspected
node scripts/generate_attestation.mjs
Referenced artifact was not completely inspected
node scripts/generate_attestation.mjs
Referenced artifact was not completely inspected
node scripts/generate_attestation.mjs
Referenced artifact was not completely inspected
node scripts/verify_attestation.mjs --input ~/.hermes/security/attestations/current.json
Referenced artifact was not completely inspected
node scripts/verify_attestation.mjs --input ~/.hermes/security/attestations/current.json
Referenced artifact was not completely inspected
node scripts/verify_attestation.mjs --input ~/.hermes/security/attestations/current.json
Referenced artifact was not completely inspected
node scripts/verify_attestation.mjs --input ~/.hermes/security/attestations/current.json
Referenced artifact was not completely inspected
node scripts/refresh_advisory_feed.mjs
Referenced artifact was not completely inspected
node scripts/refresh_advisory_feed.mjs
Referenced artifact was not completely inspected
node scripts/refresh_advisory_feed.mjs
This code goes beyond passive attestation or drift detection by actively rewriting the user's crontab via writeCrontab(). That creates a privileged state-changing capability in a skill whose stated purpose suggests observation and verification, increasing the risk of persistence, unintended task execution, or operator surprise if the skill is invoked in automation.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
return spawnSync(process.execPath, [setupScript, ...args], {
cwd: skillRoot,
encoding: "utf8",
env: { ...process.env, ...env },
});
}
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
return spawnSync(process.execPath, [setupScript, ...args], {
cwd: skillRoot,
encoding: "utf8",
env: { ...process.env, ...env },
});
}
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
return spawnSync(process.execPath, [setupScript, ...args], {
cwd: skillRoot,
encoding: "utf8",
env: { ...process.env, ...env },
});
}
The installation command uses npx skills without pinning a specific package version, which can cause operators to execute an unexpected or newly published package version at install time. In a security-sensitive skill focused on attestation and advisory verification, this weakens supply-chain trust because the bootstrap path itself is not reproducible or tightly controlled.
The skill exposes shell, network, file-read, and environment-dependent behavior but does not declare any explicit tool scope or permissions boundary. That increases the chance an agent or runtime grants broader capabilities than intended, making dangerous operations like remote fetches, local file access, and scheduled command setup easier to invoke implicitly.
Using npx skills without pinning an exact package version allows the installer to resolve whatever version is current at execution time. If the upstream package is compromised or a breaking/malicious release is published, operators may execute unreviewed code during installation.
The skill invokes an external scheduler binary and uses it to read and write crontab state, which materially expands its authority surface. Even though spawnSync is used without a shell and arguments are fixed, the ability to alter scheduled execution can be abused if scheduleBin or the command content is attacker-controlled elsewhere, and it is not clearly necessary for attestation itself.
orchestrateManagedCronRun() writes the merged crontab immediately unless printOnly is set, with no confirmation prompt or safety interlock in this code path. In operator tooling, silent scheduler modification can create persistence, break existing jobs, or cause unexpected recurring execution if called by higher-level automation or with mistaken parameters.
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.
The README repeatedly states the skill is "Hermes-only," which is a natural-language restriction to a specific agent context without any opt-in or alternative. Under the policy rule for language/locale-style organizational constraints, this is a documented forced constraint stated in natural language.
Detected: suspicious.dangerous_exec