Back to skill

Security audit

eve-esi

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed EVE Online API helper that handles sensitive OAuth tokens locally and requires explicit user action for authentication and writes.

Install from a reviewed commit or release if possible, grant only the EVE scopes needed for your task, prefer esi_query.py --char over copying tokens, avoid putting tokens in config files or command lines, and skip the optional Redis setup unless you are deliberately building the missing cache automation.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T08 · Insecure Dependencies

Warning
Location
README.md:34
Finding

Mutable Git Repository Used as an Unpinned Installation Source

Content
View full analysis
Remediation
View remediation
git verify-commit ``` ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:373
Finding

Optional Redis Python Dependency Is Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation
\ --hash=sha256: ``` - Install dependencies in a dedicated virtual environment rather than the system Python environment. - Pin the operating-system package to an approved repository/version where operationally feasible. - Do not enable Redis at boot unless persistent caching is explicitly required by the user. - Configure Redis to bind only to a local interface, disable unauthenticated remote access, and apply least-privilege service settings. - Document how to disable and remove the optional service: ```bash sudo systemctl disable --now redis-server ``` ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (45)

Tainted flow: 'req' from os.environ.get (line 315, 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/esi_query.py (reported line 318)May include surrounding context.

python
req = urllib.request.Request(url, data=data, headers=headers, method=method)

    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            resp_headers = {k.lower(): v for k, v in resp.getheaders()}
            raw = resp.read().decode("utf-8")
            try:

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full-featured EVE ESI query/management skill with token storage/refresh and optional guarded write support. This code chunk is much narrower: it only handles initial SSO authentication and local refresh-token storage. While that authentication piece is consistent with part of the description, the main claimed capabilities—reaching arbitrary ESI endpoints, reading many categories of character/public data, auto-refreshing tokens, and performing writes only under --allow-write—are not implemented here. The code also defaults to requesting a specific limited scope profile ('pi') rather than broadly enabling read-only access to any endpoint. Therefore the supplied code does not accurately represent the full declared behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a networked EVE Online API client focused on authenticating to ESI and reading/writing character/account data. The supplied code does none of that. It is a standalone CLI validator using only the Python standard library to inspect local JSON configuration files and associated schema/example files. Its EVE-specific logic is limited to checking configured alert/report names against expected ESI scopes; it does not contact ESI, perform OAuth, store tokens, or manage game data. This is a materially different primary purpose, so the description does not accurately represent the code chunk.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The skill explicitly supports handling OAuth access tokens via environment variables and local storage, which are high-value bearer credentials. In this context, the danger is not mere mention of tokens, but that the skill is designed to read, store, and potentially propagate credentials across scripts and optional integrations, expanding the attack surface for credential theft if logs, config, or process environments are exposed.

Content

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

md
required: false
    sensitive: false
  - name: EVE_TOKEN_MAIN
    description: "ESI OAuth2 access token for the main character. Not needed at runtime — scripts auto-manage tokens via ~/.openclaw/eve-tokens.json (created by auth_flow.py). Only set as env var if using $ENV: references in your dashboard config."
    required: false
    sensitive: true
  - name: EVE_REFRESH_MAIN

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

Refresh tokens are long-lived and more sensitive than short-lived access tokens because they can mint new access tokens repeatedly. Documenting and supporting their presence in environment variables or config-referenced paths creates a realistic secret-exposure risk through process inspection, shell history, misconfigured dashboards, or inherited environment leakage.

Content

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

md
required: false
    sensitive: true
  - name: EVE_REFRESH_MAIN
    description: "ESI OAuth2 refresh token for automatic access token renewal. Not needed at runtime — scripts auto-manage tokens via ~/.openclaw/eve-tokens.json. Only set as env var if using $ENV: references in your dashboard config."
    required: false
    sensitive: true
  - name: TELEGRAM_BOT_TOKEN

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

COMPAT="2026-08-04" UA="OpenClaw-ESI-Skill/1.3.3 (+https://github.com/burnshall-ui/openclaw-eve-skill)"

esi() { curl -s -H "X-Compatibility-Date: $COMPAT" -H "User-Agent: $UA" "$@"; }

text

## Public endpoints (no auth)

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The schema explicitly supports storing ESI access tokens and refresh tokens in configuration, which are highly sensitive credentials granting API access to character data and potentially write actions when broader scopes are granted. Given the skill metadata says tokens are stored locally and auto-refreshed long-term, compromise of this config or adjacent tooling could expose persistent account access and enable data theft or unauthorized actions.

Content

Scanner excerpt · config/schema.json (reported line 63)May include surrounding context.

json
},
          "token": {
            "type": "string",
            "description": "ESI Access Token (or '$ENV:EVE_TOKEN_MAIN'). Expires after ~20min."
          },
          "refresh_token": {
            "type": "string",

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/authentication.md (reported line 8)May include surrounding context.

md
Base SSO URL: `https://login.eveonline.com`
Endpoint discovery: <https://login.eveonline.com/.well-known/oauth-authorization-server>

> **Everything on this page is a secret.** Authorization codes, access tokens,
> refresh tokens, client IDs and PKCE verifiers are all bearer credentials —
> whoever holds one can act as the character. The refresh token is the one that
> matters most: access tokens expire in ~20 minutes, refresh tokens do not

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/authentication.md (reported line 11)May include surrounding context.

md
Base SSO URL: `https://login.eveonline.com`
Endpoint discovery: <https://login.eveonline.com/.well-known/oauth-authorization-server>

> **Everything on this page is a secret.** Authorization codes, access tokens,
> refresh tokens, client IDs and PKCE verifiers are all bearer credentials —
> whoever holds one can act as the character. The refresh token is the one that
> matters most: access tokens expire in ~20 minutes, refresh tokens do not

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/authentication.md (reported line 68)May include surrounding context.

Step 3: Refresh expired tokens

Access tokens expire after ~20 minutes. Refresh with:

bash
curl -X POST https://login.eveonline.com/v2/oauth/token \

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/authentication.md (reported line 88)May include surrounding context.

md
Response includes `CharacterID`, `CharacterName`, `Scopes`.

The access token is also a JWT, so the same claims can be read without a round
trip: `sub` holds `CHARACTER:EVE:<character-id>`, `name` the character name and
`scp` the granted scopes. To verify a token you did not fetch yourself, check
its signature against the JWKS URL published in the SSO metadata document, and

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/authentication.md (reported line 96)May include surrounding context.

md
Response includes `CharacterID`, `CharacterName`, `Scopes`.

The access token is also a JWT, so the same claims can be read without a round
trip: `sub` holds `CHARACTER:EVE:<character-id>`, `name` the character name and
`scp` the granted scopes. To verify a token you did not fetch yourself, check
its signature against the JWKS URL published in the SSO metadata document, and

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The script accepts an OAuth bearer token directly via the --token command-line argument. Even though the help text warns about it, passing secrets in argv can expose them to local users and monitoring tools through process listings, shell history, job control logs, and crash reporting, which is especially relevant because this skill manages long-lived EVE OAuth tokens.

Content

Scanner excerpt · scripts/esi_query.py (reported line 897)May include surrounding context.

python
parser = argparse.ArgumentParser(description="Query EVE ESI API endpoints")
    parser.add_argument("--token", required=False,
                        help="ESI access token (Bearer). Exposed via ps/shell history — "
                             "prefer --char or --token-stdin")
    parser.add_argument("--char", required=False,
                        help="Stored character key; refreshes the token in-process so it "

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/esi_query.py (reported line 167)May include surrounding context.

python
Reads refresh_token from $OPENCLAW_STATE_DIR/eve-tokens.json (default: ~/.openclaw/) and returns a fresh access_token.

Usage:
    python get_token.py --char main          # prints a short-lived access token to stdout
    python get_token.py --char main --json   # token response as JSON, refresh_token redacted
    python get_token.py --char main --char-id  # prints only the character ID
    python get_token.py --list               # list all stored characters

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/esi_query.py (reported line 200)May include surrounding context.

python
Reads refresh_token from $OPENCLAW_STATE_DIR/eve-tokens.json (default: ~/.openclaw/) and returns a fresh access_token.

Usage:
    python get_token.py --char main          # prints a short-lived access token to stdout
    python get_token.py --char main --json   # token response as JSON, refresh_token redacted
    python get_token.py --char main --char-id  # prints only the character ID
    python get_token.py --list               # list all stored characters

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/esi_query.py (reported line 903)May include surrounding context.

python
Reads refresh_token from $OPENCLAW_STATE_DIR/eve-tokens.json (default: ~/.openclaw/) and returns a fresh access_token.

Usage:
    python get_token.py --char main          # prints a short-lived access token to stdout
    python get_token.py --char main --json   # token response as JSON, refresh_token redacted
    python get_token.py --char main --char-id  # prints only the character ID
    python get_token.py --list               # list all stored characters

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/get_token.py (reported line 7)May include surrounding context.

python
Reads refresh_token from $OPENCLAW_STATE_DIR/eve-tokens.json (default: ~/.openclaw/) and returns a fresh access_token.

Usage:
    python get_token.py --char main          # prints a short-lived access token to stdout
    python get_token.py --char main --json   # token response as JSON, refresh_token redacted
    python get_token.py --char main --char-id  # prints only the character ID
    python get_token.py --list               # list all stored characters

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/get_token.py (reported line 146)May include surrounding context.

python
Reads refresh_token from $OPENCLAW_STATE_DIR/eve-tokens.json (default: ~/.openclaw/) and returns a fresh access_token.

Usage:
    python get_token.py --char main          # prints a short-lived access token to stdout
    python get_token.py --char main --json   # token response as JSON, refresh_token redacted
    python get_token.py --char main --char-id  # prints only the character ID
    python get_token.py --list               # list all stored characters

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 253)May include surrounding context.

md
CI output or agent chat transcripts. Prefer `esi_query.py --char main`,
    which resolves the token in-process and never prints it.

    Access tokens are short-lived (~20 minutes). The refresh token is NOT:
    it is a long-lived bearer credential that grants continued access to the
    account. `--json` therefore redacts it unless you pass
    `--include-refresh-token` explicitly.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
CI output or agent chat transcripts. Prefer `esi_query.py --char main`,
    which resolves the token in-process and never prints it.

    Access tokens are short-lived (~20 minutes). The refresh token is NOT:
    it is a long-lived bearer credential that grants continued access to the
    account. `--json` therefore redacts it unless you pass
    `--include-refresh-token` explicitly.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/get_token.py (reported line 17)May include surrounding context.

python
CI output or agent chat transcripts. Prefer `esi_query.py --char main`,
    which resolves the token in-process and never prints it.

    Access tokens are short-lived (~20 minutes). The refresh token is NOT:
    it is a long-lived bearer credential that grants continued access to the
    account. `--json` therefore redacts it unless you pass
    `--include-refresh-token` explicitly.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

This code prints a valid OAuth access token to stdout, which can leak into terminal scrollback, logs, CI output, agent transcripts, shell capture, or be consumed by other untrusted tooling. Even though the token is short-lived and the script warns about the risk, exposing bearer credentials through stdout is dangerous because anyone who obtains the token can impersonate the user for its lifetime against permitted ESI scopes.

Content

Scanner excerpt · scripts/get_token.py (reported line 187)May include surrounding context.

python
file=sys.stderr)
        print(json.dumps(payload, indent=2))
    else:
        print("Note: access token written to stdout (valid ~20 min). "
              "Prefer esi_query.py --char, which never prints it.", file=sys.stderr)
        print(token_data["access_token"])

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 85)May include surrounding context.

SSO shows you the same list on its consent screen. Nothing is granted until you approve it there.

Tokens land in ~/.openclaw/eve-tokens.json (chmod 600) and rotate on every use. Repeat with a different --char-name for each alt:

bash

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 224)May include surrounding context.

automation can use, and the validator tells you whether a config is well formed and whether your token covers the scopes it asks for. Wiring it to something that actually polls on a schedule and delivers to Telegram or Discord is work that lives in your agent workspace, and you have to write it.

bash
cp config/example-config.json ~/.openclaw/eve-dashboard-config.json

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 375)May include surrounding context.

live from ESI on every request.

bash
sudo apt install redis-server
sudo systemctl enable redis-server
pip3 install redis
redis-cli ping   # → PONG

Static analysis

No suspicious patterns detected.