Back to skill

Security audit

Sentinel Shield

Security checks for vulnerabilities and agentic risk

Overview

This security skill is not clearly malicious, but it overstates its automatic protections and reads sensitive system files by default, so it should be reviewed carefully before use.

Treat this as a manual auditing helper, not a dependable runtime shield. Before installing or enabling it, narrow monitoredFiles to files you explicitly want hashed, avoid running it with elevated privileges, keep Telegram disabled unless you accept sending alert data to Telegram, protect any bot token as a secret, and initialize baselines only from a known-clean state. Do not rely on its documented rate limit or kill switch to stop a compromised or runaway agent unless a separate OpenClaw enforcement integration is added.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
config/shield.json:12
Finding
Default Policy Reads Security-Critical Files Beyond the Minimum OpenClaw Scope## Vulnerability Details **File Location**: `config/shield.json:12-17`, with the read operation implemented in `scripts/fileIntegrity.js:17-24` **Vulnerability Type**: Excessive access to sensitive system and SSH files **Risk Level**: Medium ### Vulnerable Code ```json "monitoredFiles": [ "~/.openclaw/openclaw.json", "~/.ssh/authorized_keys", "/etc/passwd", "/etc/sudoers" ], ``` The configured files are read by the following implementation: ```javascript function hashFile(filePath) { try { const content = fs.readFileSync(expandPath(filePath)); return crypto.createHash('sha256').update(content).digest('hex'); } catch (e) { return e.code === 'ENOENT' ? 'FILE_NOT_FOUND' : `ERROR:${e.code}`; } } ``` ### Technical Analysis The default policy causes the process to read OpenClaw authentication configuration, the current user's SSH authorization file, and system account or privilege configuration. Reading files to calculate integrity hashes is consistent with file-integrity monitoring, but monitoring SSH and operating-system authorization files is broader than the minimum access required to protect an OpenClaw agent. The implementation reads entire files into process memory rather than hashing them through a bounded stream. Consequently, any injected code, compromised dependency, debugger, crash reporter, or future logging change operating in the same process could access the full contents. The static warning that the Skill writes to `authorized_keys` is not confirmed. The reviewed implementation only reads that file and writes its SHA-256 hash to `data/baselines.json`. It does not add, remove, or modify SSH keys. The documentation also lists `~/.openclaw/credentials`, although it is not present in the shipped default `config/shield.json`. If a user follows the documented example, that credential store will also be read in full. ### Attack Path 1. The Skill is installed unde ...[truncated 1288 chars]
Remediation
## Remediation Suggestions 1. Restrict the default list to OpenClaw files strictly required by the declared functionality. 2. Make SSH and operating-system file monitoring opt-in, with an explicit warning describing the required privileges and privacy implications. 3. Never recommend running the Skill as root solely to make otherwise inaccessible files readable. 4. Use streaming hashing through `crypto.createHash()` and `fs.createReadStream()` so entire files are not held in one process buffer. 5. Apply an allowlist or scope policy that prevents arbitrary sensitive paths from being added without explicit operator approval. 6. Reconcile `SKILL.md` with the shipped configuration, especially the inconsistent reference to `~/.openclaw/credentials`. 7. Document explicitly that `authorized_keys` is read-only and add tests confirming that no monitored target is opened with write permissions.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sentinel.js:94
Finding
Advertised Runtime Rate Limiting and Kill Switch Are Not Integrated with Tool Execution## Vulnerability Details **File Location**: `scripts/sentinel.js:12-14`, `scripts/sentinel.js:94-102`, and `scripts/sentinel.js:137-154` **Vulnerability Type**: Fail-open security control and misleading emergency-stop behavior **Risk Level**: High ### Vulnerable Code The main executable imports only rate-limit status functionality, not the function that records or blocks calls: ```javascript const { scan } = require('./injectionScanner'); const { init: initBaselines, check: checkFiles } = require('./fileIntegrity'); const { getStatus: getRateStatus, loadAlerts, saveAlert, loadConfig } = require('./monitor'); ``` The advertised kill switch only resets accounting data: ```javascript function cmd_kill() { saveAlert({ level: 'CRITICAL', type: 'KILL_SWITCH', message: 'Kill switch activated manually' }); // Reset rate counters const countsFile = path.join(BASE_DIR, 'data', 'call_counts.json'); fs.writeFileSync(countsFile, JSON.stringify({ calls: [], windowStart: Date.now() })); console.log('🔴 KILL SWITCH ACTIVATED'); console.log(' Rate counters reset'); console.log(' Kill event logged'); } ``` The CLI router exposes status and manual operations but does not wrap or intercept Agent tool calls: ```javascript switch (cmd) { case 'status': cmd_status(); break; case 'audit': cmd_audit(); break; case 'alerts': { const hoursIdx = args.indexOf('--hours'); const hours = hoursIdx >= 0 ? parseInt(args[hoursIdx + 1]) || 24 : 24; cmd_alerts(hours); break; } case 'ratelimit': cmd_ratelimit(); break; case 'kill': cmd_kill(); break; case 'scan': { const textIdx = args.indexOf('--text'); const text = textIdx >= 0 ? args.slice(textIdx + 1).join(' ') : null; cmd_scan(text); break; } case 'init': cmd_init(); break; default: console.log(`Sentinel Shield v${VERSION}`); console.log('Commands: status | audit | alerts [-- ...[truncated 3362 chars]
Remediation
## Remediation Suggestions 1. Integrate a mandatory pre-tool-call hook into the OpenClaw execution path. 2. Ensure every monitored call invokes `recordCall()` before execution and that `blocked: true` prevents dispatch. 3. Make enforcement fail closed when counter state is missing, malformed, inaccessible, or concurrently modified. 4. Implement atomic counter updates and locking to prevent concurrent calls from bypassing limits. 5. Replace the current kill behavior with a durable disabled state checked by every tool-dispatch hook. 6. Where supported, terminate or revoke the active Agent session and disable gateway credentials through an approved runtime API. 7. Do not reset rate counters during a kill operation; retain them as forensic evidence. 8. Invoke `sendTelegram()` or another configured notification mechanism for kill events and report delivery failures. 9. Automatically scan inbound untrusted content before it reaches the Agent, rather than exposing only a manual scanner. 10. Revise documentation until these integrations exist. Clearly identify status-only or advisory controls and avoid claiming automatic enforcement. 11. Add end-to-end tests proving that the fifty-first call is not executed and that the kill command blocks all subsequent calls.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fileIntegrity.js:29
Finding
Unauthenticated Baseline Reset Can Legitimize Existing Security-Critical File Changes## Vulnerability Details **File Location**: `scripts/fileIntegrity.js:29-42` and `scripts/sentinel.js:127-134` **Vulnerability Type**: Integrity-monitor baseline poisoning **Risk Level**: Medium ### Vulnerable Code Baseline initialization unconditionally replaces all existing baseline values: ```javascript function saveBaselines(baselines) { fs.mkdirSync(DATA_DIR, { recursive: true }); fs.writeFileSync(BASELINE_FILE, JSON.stringify(baselines, null, 2)); } function init(files) { const baselines = {}; for (const f of files) { baselines[f] = { hash: hashFile(f), timestamp: new Date().toISOString() }; } saveBaselines(baselines); return baselines; } ``` The command is exposed directly through the CLI: ```javascript function cmd_init() { const config = loadShieldConfig(); const baselines = initBaselines(config.monitoredFiles || []); console.log('🛡️ Baselines initialized'); for (const [file, info] of Object.entries(baselines)) { const status = info.hash.startsWith('ERROR') || info.hash === 'FILE_NOT_FOUND' ? '⚠️' : '✅'; console.log(` ${status} ${file} → ${info.hash.substring(0, 16)}...`); } saveAlert({ level: 'INFO', type: 'INIT', message: `Baselines initialized for ${Object.keys(baselines).length} files` }); } ``` ### Technical Analysis The `init` operation has no authorization check, confirmation, trusted-reference comparison, or protection against replacing an existing baseline. Any process able to invoke the CLI as the Skill's user can redefine the current state of every monitored file as trusted. The baseline database is stored under the same project directory and security context as the process being monitored. No signature, message authentication code, append-only storage, or separate privileged ownership protects it. The implementation also silently treats unreadable or missing baseline data as an empty object: ```javascript function load ...[truncated 1667 chars]
Remediation
## Remediation Suggestions 1. Refuse to overwrite an existing baseline unless an explicit, separately authorized rotation workflow is used. 2. Require interactive confirmation and an operator-provided authorization factor for baseline replacement. 3. Separate initial enrollment from baseline rotation and produce a high-severity alert for every rotation. 4. Store baselines outside the writable Skill directory under restrictive ownership and permissions. 5. Protect baseline records with a keyed message authentication code or digital signature whose key is unavailable to the monitored Agent process. 6. Use immutable or append-only external storage where practical. 7. Treat a missing, unreadable, malformed, or unsigned baseline as a critical failure, not as an empty baseline. 8. Preserve historical baselines and rotation audit records so an attacker cannot erase evidence by reinitializing. 9. Before rotation, display all differences from the previous baseline and require explicit approval for each security-critical file. 10. Document that initialization must occur only from a known-clean system state.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented behavior is primarily a manual CLI/admin interface with file baseline and reset functions, not clearly an active runtime enforcement layer. In a security skill, that mismatch is especially dangerous because users may assume continuous protection of sensitive assets such as gateway tokens and sessions when no such live control is evident.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior is primarily a manual CLI/admin interface with file baseline and reset functions, not clearly an active runtime enforcement layer. In a security skill, that mismatch is especially dangerous because users may assume continuous protection of sensitive assets such as gateway tokens and sessions when no such live control is evident.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior is primarily a manual CLI/admin interface with file baseline and reset functions, not clearly an active runtime enforcement layer. In a security skill, that mismatch is especially dangerous because users may assume continuous protection of sensitive assets such as gateway tokens and sessions when no such live control is evident.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior is primarily a manual CLI/admin interface with file baseline and reset functions, not clearly an active runtime enforcement layer. In a security skill, that mismatch is especially dangerous because users may assume continuous protection of sensitive assets such as gateway tokens and sessions when no such live control is evident.

Credential Access

High
Category
Privilege Escalation
Content
"monitoredFiles": [
    "~/.openclaw/openclaw.json",
    "~/.openclaw/credentials",
    "~/.ssh/authorized_keys",
    "/etc/passwd"
  ],
  "injectionScanning": true,
Confidence
91% confidence
Finding
The skill is configured to monitor highly sensitive paths including ~/.ssh/authorized_keys, which implies read access to security-critical authentication material. In a generic agent skill, touching such files increases the blast radius if the skill is triggered unexpectedly, compromised, or misused, even if the stated intent is integrity monitoring.

Credential Access

High
Category
Privilege Escalation
Content
"~/.openclaw/openclaw.json",
    "~/.openclaw/credentials",
    "~/.ssh/authorized_keys",
    "/etc/passwd"
  ],
  "injectionScanning": true,
  "alertLevel": "medium"
Confidence
89% confidence
Finding
Monitoring /etc/passwd implies access to system account information outside the immediate OpenClaw application scope. Although /etc/passwd is not secret in the same way as private keys, including it in a general-purpose skill expands host reconnaissance capability and may reveal environment details useful to an attacker.

Credential Access

High
Category
Privilege Escalation
Content
- `~/.openclaw/openclaw.json` — Gateway auth token (THE critical file)
- `~/.openclaw/credentials` — Stored credentials
- `~/.ssh/authorized_keys` — SSH access control
- `/etc/passwd` — System user accounts
- `/etc/sudoers` — Privilege escalation paths
Confidence
90% confidence
Finding
The documented default monitored files again include ~/.ssh/authorized_keys, underscoring access to authentication-sensitive resources. In the context of a broadly triggered skill with shell capability, this makes accidental or abusive inspection of access-control files more dangerous than in a tightly scoped system administration tool.

Credential Access

High
Category
Privilege Escalation
Content
- `~/.openclaw/openclaw.json` — Gateway auth token (THE critical file)
- `~/.openclaw/credentials` — Stored credentials
- `~/.ssh/authorized_keys` — SSH access control
- `/etc/passwd` — System user accounts
- `/etc/sudoers` — Privilege escalation paths

## Version History
Confidence
89% confidence
Finding
The default monitored file list includes /etc/passwd and nearby documentation also references /etc/sudoers, showing the skill is aimed at privileged system files beyond its declared agent-security role. This broadens the accessible security boundary and is more dangerous here because the skill is marketed for routine agent use rather than controlled system administration.

Credential Access

High
Category
Privilege Escalation
Content
},
  "monitoredFiles": [
    "~/.openclaw/openclaw.json",
    "~/.ssh/authorized_keys",
    "/etc/passwd",
    "/etc/sudoers"
  ],
Confidence
95% confidence
Finding
Monitoring ~/.ssh/authorized_keys gives the skill visibility into SSH trust relationships and persistence mechanisms unrelated to normal OpenClaw agent protection. A component with access to this file could expose sensitive access metadata or be leveraged to track or facilitate credential/persistence abuse on the host.

Credential Access

High
Category
Privilege Escalation
Content
"monitoredFiles": [
    "~/.openclaw/openclaw.json",
    "~/.ssh/authorized_keys",
    "/etc/passwd",
    "/etc/sudoers"
  ],
  "injectionScanning": true,
Confidence
96% confidence
Finding
Including /etc/passwd in monitoredFiles grants visibility into system user enumeration data beyond the skill's declared scope. While /etc/passwd is often world-readable, building this access into an agent security skill unnecessarily broadens host reconnaissance capability and can aid follow-on targeting when combined with other information.

Credential Access

High
Category
Privilege Escalation
Content
{ id: 'EXFIL_URL', re: /fetch https?:\/\/|curl |wget |send (to|data|this)/i, severity: 'high' },
  { id: 'EXFIL_WEBHOOK', re: /webhook|ngrok|requestbin|pipedream/i, severity: 'high' },
  { id: 'TOKEN_STEAL', re: /api[_\s]?key|bearer token|authorization header|gateway[_\s]?token/i, severity: 'critical' },
  { id: 'CRED_EXTRACT', re: /\.env file|credentials|password file|secret key/i, severity: 'high' },
  { id: 'SUDO_ESCAPE', re: /sudo |chmod 777|chown root|escalat/i, severity: 'high' },
  { id: 'DELIMITER_INJECT', re: /---END---|####|<\|endoftext\|>|<\|im_sep\|>/i, severity: 'critical' },
  { id: 'MULTI_PERSONA', re: /developer mode|unlock(ed)? mode|god mode|debug mode/i, severity: 'high' },
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
{ id: 'EXFIL_WEBHOOK', re: /webhook|ngrok|requestbin|pipedream/i, severity: 'high' },
  { id: 'TOKEN_STEAL', re: /api[_\s]?key|bearer token|authorization header|gateway[_\s]?token/i, severity: 'critical' },
  { id: 'CRED_EXTRACT', re: /\.env file|credentials|password file|secret key/i, severity: 'high' },
  { id: 'SUDO_ESCAPE', re: /sudo |chmod 777|chown root|escalat/i, severity: 'high' },
  { id: 'DELIMITER_INJECT', re: /---END---|####|<\|endoftext\|>|<\|im_sep\|>/i, severity: 'critical' },
  { id: 'MULTI_PERSONA', re: /developer mode|unlock(ed)? mode|god mode|debug mode/i, severity: 'high' },
  { id: 'SAFETY_BYPASS', re: /without (any )?restrictions|no (safety|ethical) (filter|guard)/i, severity: 'critical' },
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The installation guide instructs users to obtain and place a Telegram bot token in configuration but does not warn that the token is a sensitive credential equivalent to control over the bot. In a security-oriented skill, this omission increases the chance users will paste, store, or share the token insecurely, exposing alerting infrastructure and potentially leaking monitored security events.

External Transmission

Medium
Category
Data Exfiltration
Content
### Get Your Chat ID
1. Message your new bot
2. Visit: `https://api.telegram.org/bot<TOKEN>/getUpdates`
3. Find `"chat":{"id":XXXXXXXX}` in response

## Customize Monitored Files
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises and invokes shell-based commands but does not declare any tool scope such as permissions or allowed-tools. That creates an implicit execution surface where an agent may run local commands without clear user consent or policy constraints, increasing the chance of unsafe execution or misuse.

Vague Triggers

Medium
Confidence
95% confidence
Finding
Several trigger phrases such as 'check security' or 'security audit' are broad enough to match ordinary user conversation, which can cause unintended activation of the skill. Because the skill may invoke shell commands and inspect sensitive files, accidental triggering raises the risk of unauthorized actions or surprise data access.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill documents alerting behavior that sends information to Telegram but does not provide a clear in-flow warning that security events or related data may leave the local environment. In a security-oriented skill, undisclosed external transmission is particularly sensitive because logs and alerts may contain operational details, host information, or indicators tied to credentials and sessions.

External Transmission

Medium
Category
Data Exfiltration
Content
## Setup (Telegram Alerts)

1. Create a Telegram bot via @BotFather → copy the token
2. Message your bot to get your chat ID: `https://api.telegram.org/bot<TOKEN>/getUpdates`
3. Add both to `{baseDir}/config/shield.json`

## How to Use in Agent Sessions
Confidence
88% confidence
Finding
The documentation references Telegram API use, indicating external network transmission. While outbound alerting can be legitimate, it is a real security concern in this context because a security skill may forward sensitive system or incident details off-host, and the docs do not clearly constrain what is sent.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The configuration directs the skill to monitor files far outside its stated purpose of protecting OpenClaw agent sessions, including SSH and core system account files. Even if framed as security monitoring, expanding visibility into ~/.ssh/authorized_keys, /etc/passwd, and /etc/sudoers increases access to sensitive host data and creates an unnecessary capability that could be abused or repurposed.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
{ id: 'EXFIL_WEBHOOK', re: /webhook|ngrok|requestbin|pipedream/i, severity: 'high' },
  { id: 'TOKEN_STEAL', re: /api[_\s]?key|bearer token|authorization header|gateway[_\s]?token/i, severity: 'critical' },
  { id: 'CRED_EXTRACT', re: /\.env file|credentials|password file|secret key/i, severity: 'high' },
  { id: 'SUDO_ESCAPE', re: /sudo |chmod 777|chown root|escalat/i, severity: 'high' },
  { id: 'DELIMITER_INJECT', re: /---END---|####|<\|endoftext\|>|<\|im_sep\|>/i, severity: 'critical' },
  { id: 'MULTI_PERSONA', re: /developer mode|unlock(ed)? mode|god mode|debug mode/i, severity: 'high' },
  { id: 'SAFETY_BYPASS', re: /without (any )?restrictions|no (safety|ethical) (filter|guard)/i, severity: 'critical' },
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
{ id: 'EXFIL_WEBHOOK', re: /webhook|ngrok|requestbin|pipedream/i, severity: 'high' },
  { id: 'TOKEN_STEAL', re: /api[_\s]?key|bearer token|authorization header|gateway[_\s]?token/i, severity: 'critical' },
  { id: 'CRED_EXTRACT', re: /\.env file|credentials|password file|secret key/i, severity: 'high' },
  { id: 'SUDO_ESCAPE', re: /sudo |chmod 777|chown root|escalat/i, severity: 'high' },
  { id: 'DELIMITER_INJECT', re: /---END---|####|<\|endoftext\|>|<\|im_sep\|>/i, severity: 'critical' },
  { id: 'MULTI_PERSONA', re: /developer mode|unlock(ed)? mode|god mode|debug mode/i, severity: 'high' },
  { id: 'SAFETY_BYPASS', re: /without (any )?restrictions|no (safety|ethical) (filter|guard)/i, severity: 'critical' },
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
{ id: 'DELIMITER_INJECT', re: /---END---|####|<\|endoftext\|>|<\|im_sep\|>/i, severity: 'critical' },
  { id: 'MULTI_PERSONA', re: /developer mode|unlock(ed)? mode|god mode|debug mode/i, severity: 'high' },
  { id: 'SAFETY_BYPASS', re: /without (any )?restrictions|no (safety|ethical) (filter|guard)/i, severity: 'critical' },
  { id: 'CONTEXT_STUFF', re: /repeat the following \d+ times|fill the context/i, severity: 'medium' },
  { id: 'INDIRECT_INJECT', re: /when the (ai|agent|assistant) reads this/i, severity: 'high' },
  { id: 'CHAIN_ATTACK', re: /step 1:.*step 2:.*step 3:/is, severity: 'medium' },
];
Confidence
85% confidence
Finding
Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Context-Inappropriate Capability

Medium
Confidence
83% confidence
Finding
The code transmits security events to Telegram, a third-party external service, which can expose operational metadata such as tool names, rate-limit conditions, and incident timing outside the local trust boundary. In the context of a security-monitoring skill, exporting alerts off-platform without strong justification or minimization increases confidentiality and compliance risk if the channel is misconfigured, compromised, or unauthorized.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The Telegram transmission occurs silently in code with no user-facing disclosure, making it easy for operators to enable or inherit external alerting without understanding that security events are being sent to a third party. This is especially concerning in a security-focused skill because users may assume monitoring remains local while sensitive operational telemetry is exfiltrated externally.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill metadata promises prompt-injection scanning and suspicious-behavior monitoring, but this file only performs rate-limit counting and Telegram alerting. In a security product, this feature mismatch can create a false sense of protection, causing operators to rely on defenses that do not actually exist and miss active attacks.