Back to skill

Security audit

AEGIS

Security checks for vulnerabilities and agentic risk

Overview

The skill largely matches emergency monitoring, but needs review because it handles credentials and safety-related location data with weak scoping and incomplete disclosure.

Review before installing. Use local-only mode where possible, avoid entering cloud LLM or NewsAPI keys unless you accept plaintext local storage, verify file permissions under ~/.openclaw, and only configure Telegram if you are comfortable sending alert content and monitoring context to that channel. Treat the current country support as UAE/Dubai-focused unless you have reviewed and adapted the profiles and scripts for another location.

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 (4)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/aegis_onboard.py:113
Finding

API credentials are stored in a plaintext configuration file without enforced restrictive permissions

Content
View full analysis
Remediation
View remediation
" if "telegram" in display: display["telegram"]["bot_token"] = "" ``` 6. Document credential storage, rotation, and revocation procedures. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/aegis_channel.py:24
Finding

The Telegram publisher loads unrelated credentials from the shared OpenClaw secret store

Content
View full analysis
/openclaw-secrets/.env (decrypted by openclaw-secrets.service) with fallback to ~/.openclaw/.env for development. Also resolves simple ${VAR} and $VAR references. """ import pwd uid = os.getuid() # Primary: tmpfs-decrypted secrets (production) env_path = Path(f'/run/user/{uid}/openclaw-secrets/.env') if not env_path.exists(): # Fallback: direct .env (development only) env_path = Path(Path.home() / '.openclaw' / '.env') if not env_path.exists(): return {} out = {} # first pass: parse for line in env_path.read_text().splitlines(): line = line.strip() if not line or line.startswith('#') or '=' not in line: continue k, v = line.split('=', 1) k = k.strip() v = v.strip().strip('"').strip("'") if k and v: out[k] = v # second pass: resolve ${VAR} and $VAR using values from out and os.environ import re pattern = re.compile(r"\$(?:\{([^}]+)\}|(\w+))") def resolve_val(val, depth=0): if depth>5 or not isinstance(val,str): return val def repl(m): name = m.group(1) or m.group(2) return out.get(name, os.environ.get(name, '')) new = pattern.sub(repl, val) if new==val: return new return resolve_val(new, depth+1) for k in list(out.keys()): out[k]=resolve_val(out[k]) # do not override existing environment variables for k,v in list(out.items()): if k not in os.environ: # put into os.environ temporarily for other code paths os.environ[k]=v return out `` ...[truncated 2037 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/aegis_scanner.py:396
Finding

NewsAPI credentials are exposed in curl process arguments and request URLs

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/aegis_scanner.py:551
Finding

LLM bearer tokens are exposed in curl process arguments

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (66)

Tainted flow: 'req' from os.environ.get (line 109, credential/environment) → urllib.request.urlopen (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 · scripts/aegis_channel.py (reported line 111)May include surrounding context.

python
req = urllib.request.Request(url, data=payload, headers={"Content-Type": "application/json"})
    try:
        resp = urllib.request.urlopen(req, timeout=15)
        result = json.loads(resp.read())
        
        # Auto-pin if requested

Tainted flow: 'pin_req' from os.environ.get (line 123, credential/environment) → urllib.request.urlopen (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 · scripts/aegis_channel.py (reported line 125)May include surrounding context.

python
}).encode()
            pin_req = urllib.request.Request(pin_url, data=pin_payload, headers={"Content-Type": "application/json"})
            try:
                urllib.request.urlopen(pin_req, timeout=10)
            except Exception:
                pass  # Pin failure is non-critical

Tainted flow: 'req2' from os.environ.get (line 138, credential/environment) → urllib.request.urlopen (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 · scripts/aegis_channel.py (reported line 139)May include surrounding context.

python
"disable_web_page_preview": True
            }).encode()
            req2 = urllib.request.Request(url, data=payload2, headers={"Content-Type": "application/json"})
            resp2 = urllib.request.urlopen(req2, timeout=15)
            return json.loads(resp2.read())
        except Exception as e2:
            print(f"[AEGIS] Send failed: {e2}", file=sys.stderr)

Tainted flow: 'pin_req' from os.environ.get (line 330, credential/environment) → urllib.request.urlopen (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 · scripts/aegis_feed.py (reported line 332)May include surrounding context.

python
}).encode()
            pin_req = urllib.request.Request(pin_url, data=pin_payload, headers={"Content-Type": "application/json"})
            try:
                urllib.request.urlopen(pin_req, timeout=10)
            except:
                pass

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code is broadly related to the declared emergency threat-monitoring purpose, but the description overstates its scope and generality. This chunk does not implement a generic 'conflict zones' intelligence system; it is a cron orchestration script specialized for UAE/Dubai alert text and behavior. It runs another scanner, logs/saves results, applies cooldown and corroboration logic, and posts critical alerts through Telegram. Those behaviors support the declared purpose, but the hard-coded UAE/Dubai targeting is a material mismatch from the description's broad, location-agnostic framing.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The description presents a broad automated emergency geopolitical intelligence system for civilians in conflict zones, suitable for monitoring any location, assessing threat levels, configuring alerts, generating briefings, and preparedness planning. The code is much narrower: it specifically filters for UAE/Gulf relevance, scrapes World Monitor and LiveUAMap, deduplicates event text, assigns coarse urgency labels, and posts batched updates to a Telegram channel. That supports part of the declared alerting/monitoring concept, but it does not implement several major claimed uses such as general location setup, comprehensive security briefings, emergency preparedness planning, or broad civilian safety analysis. It also uses undeclared external network resources and Telegram posting. Therefore the code only partially matches the description and is materially narrower/different in purpose and capability.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a full emergency geopolitical intelligence and civilian safety alerting system focused on monitoring, threat analysis, briefing generation, and preparedness workflows. The provided code does not perform monitoring, intelligence gathering, threat assessment, alert delivery, briefing generation, or preparedness planning. Instead, it is a narrow operational script for toggling a single cron-based live feed on or off and checking its status. While this may support a larger AEGIS system, the actual code chunk’s primary purpose is infrastructure/task scheduling control, which is materially different from the declared end-user functionality.

Content

No source excerpt is available for this finding.

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 · scripts/aegis_channel.py (reported line 27)May include surrounding context.

python
def _load_openclaw_dotenv():
    """Best-effort loader for decrypted secrets from tmpfs.

    Reads from /run/user/<uid>/openclaw-secrets/.env (decrypted by
    openclaw-secrets.service) with fallback to ~/.openclaw/.env for
    development. Also resolves simple ${VAR} and $VAR references.
    """

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 · scripts/aegis_channel.py (reported line 28)May include surrounding context.

python
def _load_openclaw_dotenv():
    """Best-effort loader for decrypted secrets from tmpfs.

    Reads from /run/user/<uid>/openclaw-secrets/.env (decrypted by
    openclaw-secrets.service) with fallback to ~/.openclaw/.env for
    development. Also resolves simple ${VAR} and $VAR references.
    """

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 · scripts/aegis_channel.py (reported line 75)May include surrounding context.

python
def _load_openclaw_dotenv():
    """Best-effort loader for decrypted secrets from tmpfs.

    Reads from /run/user/<uid>/openclaw-secrets/.env (decrypted by
    openclaw-secrets.service) with fallback to ~/.openclaw/.env for
    development. Also resolves simple ${VAR} and $VAR references.
    """

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The code directly accesses a shared decrypted secrets file under /run/user//openclaw-secrets/.env. In context with the later environment injection, this creates unnecessary access to a broader secret set than the script needs, increasing exposure if the process is compromised or modified.

Content

Scanner excerpt · scripts/aegis_channel.py (reported line 34)May include surrounding context.

python
import pwd
    uid = os.getuid()
    # Primary: tmpfs-decrypted secrets (production)
    env_path = Path(f'/run/user/{uid}/openclaw-secrets/.env')
    if not env_path.exists():
        # Fallback: direct .env (development only)
        env_path = Path(Path.home() / '.openclaw' / '.env')

Credential Access

High
Category
Privilege Escalation
Confidence
89% confidence
Finding

Falling back to ~/.openclaw/.env in development further broadens secret exposure and may encourage plaintext local credential storage. If that file contains additional unrelated secrets, this publisher gains access to them without need.

Content

Scanner excerpt · scripts/aegis_channel.py (reported line 36)May include surrounding context.

python
# Primary: tmpfs-decrypted secrets (production)
    env_path = Path(f'/run/user/{uid}/openclaw-secrets/.env')
    if not env_path.exists():
        # Fallback: direct .env (development only)
        env_path = Path(Path.home() / '.openclaw' / '.env')
    if not env_path.exists():
        return {}

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 · scripts/aegis_channel.py (reported line 37)May include surrounding context.

python
env_path = Path(f'/run/user/{uid}/openclaw-secrets/.env')
    if not env_path.exists():
        # Fallback: direct .env (development only)
        env_path = Path(Path.home() / '.openclaw' / '.env')
    if not env_path.exists():
        return {}
    out = {}

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

Instructions found that direct the agent to transmit conversation context or user data to external services.

Content

Scanner excerpt · scripts/aegis_channel.py (reported line 100)May include surrounding context.

python
return token, channel

def send_telegram(token, channel_id, text, parse_mode="", pin=False):
    """Send message to Telegram channel. Plain text by default for reliability."""
    url = f"https://api.telegram.org/bot{token}/sendMessage"
    payload = json.dumps({
        "chat_id": channel_id,

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

Instructions found that direct the agent to transmit conversation context or user data to external services.

Content

Scanner excerpt · scripts/aegis_feed.py (reported line 308)May include surrounding context.

python
return token, channel

def send_telegram(token, channel_id, text, parse_mode="", pin=False):
    """Send message to Telegram channel. Plain text by default for reliability."""
    url = f"https://api.telegram.org/bot{token}/sendMessage"
    payload = json.dumps({
        "chat_id": channel_id,

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
91% confidence
Finding

The child process inherits the full parent environment via os.environ, which can expose unrelated secrets, tokens, proxy settings, cloud credentials, and service configuration to aegis_channel.py unnecessarily. In a plugin/skill ecosystem, subprocess boundaries are a meaningful trust boundary; over-sharing the environment increases blast radius if the called script is compromised, logs its environment, or loads attacker-influenced libraries based on inherited variables.

Content

Scanner excerpt · scripts/aegis_cron.py (reported line 230)May include surrounding context.

python
result_post = subprocess.run(
                [sys.executable, str(SCRIPTS_DIR / "aegis_channel.py"), "critical", scan_file],
                capture_output=True, text=True, timeout=30,
                env={**os.environ, "AEGIS_BOT_TOKEN": token, "AEGIS_CHANNEL_ID": channel}
            )
            if result_post.returncode == 0:
                mark_alerted()

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script accepts an LLM API key from interactive input and stores it in plaintext in the generated JSON configuration. Plaintext secret storage is dangerous because any process, user, backup system, or support workflow with filesystem access can recover and misuse the credentials.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README instructs users to configure Telegram channel delivery by exporting a bot token and channel ID, but it does not clearly disclose that alert content and related metadata will be sent to Telegram, a third-party service outside the operator's control. In a conflict-zone intelligence skill, alerts may reveal sensitive location, threat-monitoring behavior, or operational context, so omission of this privacy/data-sharing warning can lead users to expose safety-relevant information without informed consent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documentation declares binaries and environment needs but does not define an explicit tool/permission scope despite describing shell execution, network access, local file reads/writes, and environment-variable use. In an agent ecosystem, this under-specification can cause the host or user to approve a skill without understanding its real privileges, increasing the risk of overbroad execution and unintended data exposure.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The skill stores persistent local configuration and operational state, including user location, alert preferences, scan history, and potentially Telegram configuration. In the context of a conflict-zone safety tool, this data can be sensitive: unauthorized local access could reveal whereabouts, habits, and communication channels, creating privacy and physical-safety risk.

Content

Scanner excerpt · SKILL.md (reported line 46)May include surrounding context.

Creates ~/.openclaw/aegis-config.json with location, language, and alert preferences.

Manual config

Create ~/.openclaw/aegis-config.json:

json
{
  "location": {

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The skill transmits data to external services, including Telegram, and the transmitted content may include sensitive location-specific threat context, alert content, or metadata derived from the user's configuration. Even though Telegram delivery is described as optional, external transmission creates privacy and data-handling risk, especially for users in conflict zones where channel exposure, bot-token misuse, or misdirected posting could endanger people.

Content

Scanner excerpt · SKILL.md (reported line 130)May include surrounding context.

md
1. URLs listed in `references/source-registry.json` (RSS feeds, news sites, government pages)
2. `https://world-monitor.com/api/signal-markers` (World Monitor public API)
3. LiveUAMap regional pages (e.g., `https://iran.liveuamap.com`)
4. Telegram Bot API (`https://api.telegram.org/bot.../sendMessage`) — only if channel delivery is configured

No telemetry. No analytics. No phone-home.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The briefing format explicitly states updates are provided 'in plain English,' which is a language constraint in the skill's natural-language behavior. Although the config example includes a language field earlier, this section does not present language choice for generated briefings and reads as a fixed requirement.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation presents a cloud LLM configuration that sends alert content to a third-party API endpoint, but it does not explicitly warn users that potentially sensitive safety-monitoring data may leave the local device and be processed by an external provider. In the AEGIS context, alerts may include location, threat context, and user-specific monitoring scope, so the omission can lead to unintentional data exposure and poor privacy decisions by users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This JSON template sets "language": "en" as a fixed default, which can encode a language preference across all generated country profiles. Because the file provides no user choice, opt-in mechanism, or documented region-specific justification, it may violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This section switches into UAE-specific evacuation routes and assumptions without prominently scoping the document as UAE-only or requiring the user to confirm location. In an emergency-preparedness skill, users may overgeneralize these routes, border assumptions, and airport options to other regions, which can cause dangerous misrouting, border denial, or movement into less safe areas during a crisis.

Content

No source excerpt is available for this finding.