Back to skill

Security audit

Nexus Sentinel

Security checks for vulnerabilities and agentic risk

Overview

This SRE skill is mostly coherent with its stated purpose, but it asks for powerful system, file, service-control, and outbound-network capabilities without enough scoping or safeguards.

Install only in a controlled SRE environment after limiting it to specific services, paths, and destinations. Require explicit approval before cleanup, restart, backup, or sending log-derived content externally, and add redaction plus content-based secret detection before enabling WhatsApp or cloud backup features.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T09 · Insecure Skill Coding Practices

Warning
Location
sentinel.py:35
Finding

Unredacted notification content may disclose sensitive information to an external service

Content
View full analysis

Vulnerability Details

File Location: sentinel.py, lines 35–45
Vulnerability Type: Unfiltered transmission of potentially sensitive diagnostic data
Risk Level: Medium

python
def notify(message):
    """Sends notification via the configured channel."""
    target = os.getenv("NEXUS_REPORT_CHANNEL")
    api_key = os.getenv("MATON_API_KEY")
    if not target or not api_key:
        print(f"NOTIFY_STDOUT: {message}")
        return
    
    # We use Maton API for secure relay
    payload = {"to": target, "message": f"[NEXUS] {message}"}
    try:
        requests.post(f"{API_GATEWAY}/whatsapp/send", json=payload, headers={"Authorization": f"Bearer {api_key}"}, timeout=10)

Technical Analysis

The function sends caller-controlled message content to https://gateway.maton.ai/whatsapp/send without redaction, classification, or explicit approval. The request also includes the configured WhatsApp destination and the MATON_API_KEY bearer credential.

Sending a bearer token to the API endpoint is necessary for the documented WhatsApp integration and is not, by itself, evidence of malicious exfiltration. However, the unrestricted message field creates a sensitive-data disclosure channel. Service logs and diagnostic output commonly contain credentials, authorization headers, connection strings, personal information, and internal infrastructure details.

The current command-line entry point does not invoke notify(), so this package does not presently demonstrate an automatic path from log collection to network transmission. Exploitation requires another caller to pass sensitive content to the function.

Attack Path

  1. A monitored Docker or PM2 service emits a credential, token, connection string, or other confidential value in its logs.
  2. Diagnostic logic or another caller obtains that content and passes it to notify().
  3. The function places the complete content in the JSON message ...[truncated 829 chars]
Remediation
View remediation

Remediation Suggestions

  • Apply a centralized redaction function before constructing the notification payload.
  • Detect and remove API keys, bearer tokens, passwords, private keys, connection strings, cookies, and authorization headers.
  • Prefer structured, allowlisted notification fields over arbitrary log or exception text.
  • Require explicit user approval before sending log-derived content externally.
  • Reject messages containing suspected secrets rather than relying solely on substitution.
  • Limit message length and avoid transmitting full stack traces or raw logs.
  • Validate the destination and restrict outbound access to the documented Maton HTTPS endpoint.
  • Check the HTTP response and report failures securely rather than suppressing every exception.
  • Ensure fallback output does not print secrets to terminals or centralized process logs.

T09 · Insecure Skill Coding Practices

Warning
Location
sentinel.py:48
Finding

Backup sensitivity control checks filenames but not file contents

Content
View full analysis

Vulnerability Details

File Location: sentinel.py, lines 48–56
Vulnerability Type: Inadequate secret detection and authorization enforcement
Risk Level: Medium

python
def backup_file(file_path):
    """Incremental backup of non-sensitive config files."""
    if any(p in file_path.lower() for p in SENSITIVE_PATTERNS):
        return {"error": "Manual authorization required for sensitive files"}
    
    # Logic to tar and push to GDrive via Maton
    # ... (Simplified for the skill demo)
    return {"status": "ready_for_upload", "file": file_path}

Technical Analysis

The documented policy prohibits uploading files containing secrets without explicit /approve authorization. The implementation only compares sensitive keywords against the textual file path. It never inspects the file's contents and does not implement or verify an approval state.

Consequently, an innocuously named file such as config.yaml could contain passwords or tokens and still be marked ready_for_upload. The substring approach also produces false positives; for example, a benign path containing the characters key would be blocked.

No upload is implemented in the audited version, so the current function only returns an unsafe readiness decision. The vulnerability becomes directly exploitable if a downstream uploader trusts that result, as implied by the documented Google Drive backup functionality.

Attack Path

  1. A secret is stored in a file whose path does not contain .env, key, password, secret, or token.
  2. The file path is passed to backup_file().
  3. The filename-based check finds no matching substring.
  4. The function returns {"status": "ready_for_upload", ...} without inspecting the content or verifying approval.
  5. A downstream backup component trusts this status and uploads the file to cloud storage.
  6. Anyone with access to the target storage or relay infrastructure can obtain the s ...[truncated 606 chars]
Remediation
View remediation

Remediation Suggestions

  • Enforce secret detection inside the final upload operation rather than treating a preliminary status as authorization.
  • Inspect file contents using well-tested secret-detection rules for credentials, tokens, private keys, and connection strings.
  • Use explicit allowlists for approved configuration roots, extensions, and file types.
  • Reject symbolic links and verify canonical paths to prevent path-policy bypasses.
  • Apply file-size limits and avoid scanning or uploading special device files.
  • Implement a cryptographically or session-bound approval record that identifies the exact file, content hash, destination, and expiration time.
  • Require explicit approval whenever secret detection is uncertain.
  • Encrypt backups in transit and at rest and restrict access to the destination folder.
  • Record security-relevant backup decisions without writing secret values to logs.

T08 · Insecure Dependencies

Note
Location
SKILL.md:18
Finding

Python dependencies are installed without version or integrity pinning

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 18–21
Vulnerability Type: Unpinned third-party dependencies
Risk Level: Low

markdown
## 🚀 Installation & Dépendances
Ce skill nécessite :
- `docker`, `pm2`, `tar`, `curl` sur le système hôte.
- Les librairies Python `psutil` et `requests`.
Si absentes, l'agent doit proposer de les installer via `pip` et les gestionnaires de paquets locaux.

The same unpinned package declarations also appear in _meta.json:

json
"requirements": {
  "binaries": ["docker", "pm2", "tar", "curl"],
  "pythonPackages": ["psutil", "requests"],
  "env": ["NEXUS_REPORT_CHANNEL", "NEXUS_BACKUP_PATH", "MATON_API_KEY"]
}

Technical Analysis

The Skill instructs the agent to offer installation of psutil and requests through pip, but it specifies neither reviewed versions nor package hashes. Package resolution therefore depends on mutable repository state at installation time.

The package names are established dependencies, are not apparent typos, and no untrusted package index is explicitly configured. The finding is therefore a supply-chain hardening weakness rather than evidence that a malicious dependency is currently included.

Attack Path

  1. The required Python packages are absent from the host.
  2. The agent proposes or performs installation using the unpinned package names.
  3. The package index resolves whatever release is current at that time.
  4. A compromised, malicious, or unexpectedly incompatible release is downloaded.
  5. Package installation or import executes unintended behavior with the privileges of the installing or running process.

Impact Assessment

Impact depends on the privileges used for installation and execution. A compromised dependency could access environment variables, including MATON_API_KEY, inspect data readable by the process, issue outbound requests, or execute local code.

If installation ...[truncated 239 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin each Python dependency to a reviewed version or tightly controlled version range.
  • Use a lockfile or requirements file with cryptographic hashes.
  • Install only from explicitly trusted package indexes over authenticated HTTPS.
  • Review dependency updates before changing pinned versions.
  • Avoid automatic installation and require informed user confirmation.
  • Install dependencies in an isolated virtual environment under a non-administrative account.
  • Apply equivalent version controls to external binaries where the deployment environment supports them.
  • Add software-composition analysis and vulnerability scanning to the release process.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (13)

Tainted flow: 'payload' from os.getenv (line 43, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · sentinel.py (reported line 45)May include surrounding context.

python
# We use Maton API for secure relay
    payload = {"to": target, "message": f"[NEXUS] {message}"}
    try:
        requests.post(f"{API_GATEWAY}/whatsapp/send", json=payload, headers={"Authorization": f"Bearer {api_key}"}, timeout=10)
    except:
        pass

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · sentinel.py (reported line 9)May include surrounding context.

python
import datetime

# --- CONFIGURATION ---
SENSITIVE_PATTERNS = [".env", "key", "password", "secret", "token"]
API_GATEWAY = "https://gateway.maton.ai"

def get_system_report():

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire skill description and operational instructions are presented only in French, with no indication that the user can choose another language or that the skill is intentionally region-specific. This can violate language/locale policy when a specific language is imposed without opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README advertises actions that can modify the host system, including log rotation, temp-file cleanup, and service recovery with restart, but it does not clearly warn users that these operations may be destructive or disruptive. In an autonomous SRE context, undocumented cleanup and restart behavior increases the risk of accidental data loss, service interruption, or unsafe execution by users who may assume the commands are read-only.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Le document décrit la rotation des logs, le nettoyage des fichiers temporaires et la récupération d'un service avec redémarrage, qui peuvent affecter des données utilisateur ou l'intégrité du système. Aucune mise en garde explicite n'indique ces impacts potentiels, les prérequis, ni les risques associés à ces actions.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes the skill as an 'Autonomous SRE Agent' that performs 'Proactive monitoring' and 'smart service recovery' without defining clear activation boundaries, approval requirements, or scope limits. In a skill that also requests filesystem write access, outbound network access, and service-control commands, this ambiguity increases the chance of unsupervised or overbroad actions affecting live systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest requests filesystem read/write access, outbound network access, and operational commands such as docker, pm2, and tar, but it does not present a clear user-facing warning about these capabilities or their risks. Because the skill is positioned for autonomous SRE activity, missing disclosure can lead operators to enable a powerful skill without understanding it can modify files, interact with services, create archives, and send data externally.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · sentinel.py (reported line 26)May include surrounding context.

python
try:
        if service_name.startswith("docker:"):
            container = service_name.split(":")[1]
            res = subprocess.run(["docker", "logs", "--tail", str(lines), container], capture_output=True, text=True)
            return res.stdout + res.stderr
        else:
            res = subprocess.run(["pm2", "logs", service_name, "--lines", str(lines), "--nostream"], capture_output=True, text=True)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
83% confidence
Finding

The code passes a user-controlled service_name directly to pm2 logs, which can expose arbitrary process logs available to the executing user. While this is not shell injection, it can enable unauthorized log access and disclosure of secrets present in application logs.

Content

Scanner excerpt · sentinel.py (reported line 29)May include surrounding context.

python
res = subprocess.run(["docker", "logs", "--tail", str(lines), container], capture_output=True, text=True)
            return res.stdout + res.stderr
        else:
            res = subprocess.run(["pm2", "logs", service_name, "--lines", str(lines), "--nostream"], capture_output=True, text=True)
            return res.stdout
    except:
        return "Log extraction failed."

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The notify function sends messages to an external API with no user confirmation, audit prompt, or content classification. In this skill context, messages may contain system state or log-derived data, so silent outbound transmission increases the chance of unreviewed data leakage.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This code performs external network transmission to a third-party gateway. In an operational diagnostics skill, outbound messaging is not inherently malicious, but it becomes security-relevant because the transmitted message may contain sensitive operational details and the transfer is silent on failure and success.

Content

Scanner excerpt · sentinel.py (reported line 45)May include surrounding context.

python
# We use Maton API for secure relay
    payload = {"to": target, "message": f"[NEXUS] {message}"}
    try:
        requests.post(f"{API_GATEWAY}/whatsapp/send", json=payload, headers={"Authorization": f"Bearer {api_key}"}, timeout=10)
    except:
        pass

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The docstring claims only non-sensitive config files are backed up, but the implementation merely checks for a few substrings in the path. This is easy to bypass and can misclassify both sensitive and non-config files, creating a path to unintended backup or later exfiltration of confidential data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

Tout le contenu descriptif et les consignes utilisateur sont rédigés exclusivement en français, sans mention d'une option de langue ou d'une contrainte régionale justifiée. Cela constitue une contrainte linguistique implicite pouvant contrevenir à une politique de neutralité linguistique sans opt-in utilisateur.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.