Back to skill

Security audit

erxes Skill

Security checks for vulnerabilities and agentic risk

Overview

This erxes skill is a disclosed admin-style GraphQL helper, but it assumes owner-level access and accepts unvalidated login endpoints for sensitive tokens.

Install only for trusted erxes environments where you are comfortable granting admin-like GraphQL access. Use HTTPS trusted gateway URLs, avoid untrusted ERXES_BASE_URL values, watch for the browser approval origin, and require explicit confirmation for deletes, transfers, publishes, contract/invoice changes, member administration, and automation changes.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/login.sh:7
Finding

Unvalidated Gateway URL Permits Credential Transmission over Plaintext or to an Untrusted Host

Content
View full analysis
&2 exit 1 fi # Extract subdomain from a gateway URL like https://demo.next.erxes.io/gateway -> demo SUB=$(echo "$BASE" | sed -E 's|https?://([^./]+).*|\1|') RESP=$(curl -sf -X POST "$BASE/oauth/device/code" \ -H "Content-Type: application/json" \ -H "erxes-subdomain: $SUB" \ -d "{\"client_id\":\"$CLIENT\"}") ``` ```bash TOK=$(curl -s -X POST "$BASE/oauth/token" \ -H "Content-Type: application/json" \ -H "erxes-subdomain: $SUB" \ -d "{\"grant_type\":\"urn:ietf:params:oauth:grant-type:device_code\",\"device_code\":\"$DC\",\"client_id\":\"$CLIENT\"}") ``` The corresponding instructions explicitly permit an HTTP endpoint: ```bash ERXES_BASE_URL=http://localhost:4000 ERXES_CLIENT_ID=my-client bash scripts/login.sh ``` ### Technical Analysis The login helper verifies only that `ERXES_BASE_URL` is nonempty. It does not securely parse or validate the URL's scheme, hostname, port, user-information component, or destination class. Consequently, the OAuth device code and token requests may be sent over plaintext HTTP or to an attacker-controlled server. The Skill subsequently instructs the Agent to use the returned bearer token and subdomain for authenticated GraphQL requests. This behavior is necessary when communicating with a legitimate erxes gateway, but accepting arbitrary endpoints and plaintext transport exceeds the minimum safe privileges needed for that functionality. Shell quoting prevents direct shell metacharacter expansion in `BASE`, but it does not prevent server impersonation, TLS downgrade, DNS manipulation, or credential transmission to an untrusted origin. ### Attack Path 1. An attacker ...[truncated 1080 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/login.sh:22
Finding

Server-Controlled Verification URI Is Opened without Scheme or Origin Validation

Content
View full analysis
/$SUB/g") if [ -z "$DC" ] || [ -z "$URI" ]; then echo "Failed to start OAuth device flow" >&2 echo "$RESP" >&2 exit 1 fi echo "Open this URL in your browser to approve access:" >&2 echo "$URI" >&2 open "$URI" 2>/dev/null || true ``` ### Technical Analysis The verification URI is extracted directly from the remote gateway response and passed to the operating system's `open` command. There is no validation that the URI uses HTTPS, belongs to the expected gateway or identity-provider origin, or avoids dangerous custom protocols. The argument is quoted, so ordinary shell command substitution in the URI is not evaluated by the shell. However, quoting does not address protocol-handler risks. On systems with registered custom schemes, `open` may dispatch the URI to an application other than a web browser. A malicious or compromised gateway can also direct the user to a convincing phishing page. This is best classified as insecure URL handling rather than confirmed remote code execution: the audited code does not download and execute a program, but it delegates a remotely controlled URI to the local operating system. ### Attack Path 1. The configured gateway is malicious, compromised, or reached through an insecure HTTP connection. 2. It returns an attacker-selected `verification_uri_complete`. 3. The script performs only a nonempty check on that value. 4. The script invokes `open` with the attacker-controlled URI. 5. The operating system opens a phishing page or dispatches a custom protocol handler. 6. The user may disclose credentials, approve access at the wrong origin, or trigger un ...[truncated 417 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:38
Finding

Owner-Mode Assumption Bypasses Least-Privilege Workflow Design

Content
View full analysis
` and `erxes-subdomain: ` headers on GraphQL calls. - If the access token expires during the current task, use the in-memory `refreshToken` to get a new access token. - Do not write tokens to `.auth.json` or any other project file. - Read [erxes-graphql-api.md](./erxes-graphql-api.md) only when you need query or mutation examples. - Assume OpenClaw is operating as the erxes owner unless the live API proves otherwise. - Do not stop a normal workflow just because the backend source defines permission names. Treat those as implementation detail, not a user-facing blocker. ``` Equivalent owner-mode assumptions also appear in `block-api.md:9` and `operation-api.md:9, 31`. ### Technical Analysis The Skill explicitly directs the Agent to presume owner-level authority and to proceed until the live API rejects an operation. This reverses the principle of least privilege: authorization is treated as an error-detection mechanism rather than a boundary that should be established before sensitive access. The declared functionality includes reading personal contact information and managing team members, documents, automations, projects, property units, opportunities, contracts, offers, invoices, tasks, statuses, and organizational structure. Although some destructive operations require confirmation, confirmation does not reduce the permissions granted to the token or prevent overbroad read access. The use of bearer tokens is necessary for the declared API functionality. The security issue is the default owner-wide authority and instruction to disregard known permission names, not authenticated API communication itself. ### Attack Path 1. The Skill authenticat ...[truncated 982 chars]
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 (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is described as a GraphQL CRUD helper, but it also performs browser-based OAuth login, token handling, and session setup. This mismatch can mislead reviewers and users about the real privileges and behaviors of the skill, making it easier to conceal sensitive auth flows or overbroad capabilities.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

The skill explicitly handles access and refresh tokens and instructs the agent to send bearer tokens in requests while assuming owner-mode access unless rejected. Even though it says not to print or persist tokens, this is still sensitive credential handling; if the session is exposed through logs, memory leaks, prompt injection, or overbroad tool access, an attacker could gain high-privilege API access.

Content

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

md
- Read `accessToken` from the login JSON response.
- Send `Authorization: Bearer <accessToken>` and `erxes-subdomain: <subdomain>` headers on GraphQL calls.
- If the access token expires during the current task, use the in-memory `refreshToken` to get a new access token.
- Do not write tokens to `.auth.json` or any other project file.
- Read [erxes-graphql-api.md](./erxes-graphql-api.md) only when you need query or mutation examples.
- Assume OpenClaw is operating as the erxes owner unless the live API proves otherwise.

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instruction to assume OpenClaw is operating as the erxes owner by default grants maximal authority without user opt-in or runtime verification. In an agent setting, this can normalize privileged execution for ordinary requests and materially increase the chance of unauthorized destructive, financial, or administrative actions across projects, contracts, invoices, and developer data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The instruction to assume OpenClaw is operating as the erxes owner by default grants an unjustified elevated trust model across destructive and administrative workflows. If the runtime session is not truly owner-scoped, the agent may attempt actions beyond the user's intended or authorized access, increasing risk of unauthorized modification or deletion.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Defaulting to owner-mode operation is effectively a policy bypass instruction: it tells the agent to treat privileged access as normal. In a skill that supports create, update, delete, member management, and status/cycle control, this can drive unauthorized privileged API calls or normalize overbroad access assumptions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Deferring permission handling until after attempting a privileged API call means the agent probes or executes against protected operations first and only treats rejection as a signal afterward. This is dangerous because it encourages unauthorized attempts, creates avoidable audit noise, and can succeed unexpectedly in misconfigured environments.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes a shell script for authentication but does not declare any tool scope or allowed-tools restrictions. That creates an unnecessary trust gap: an agent could execute shell-capable behavior without explicit capability boundaries, increasing the chance of unintended command execution or abuse if the skill or referenced files are modified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill title and many capability sections are written in Mongolian, while other operational instructions and examples are in English. This imposes a mixed-language experience without stating that the user can choose their preferred language or that the skill is limited to a specific locale.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
- `ERXES_CLIENT_ID` is optional. Default to `erxes-local`.
- Accept the URL in whatever form the user gives and normalize it to `ERXES_BASE_URL=<url>`.
- Do not explain OAuth internals unless the user asks.
- Do not ask the user to copy tokens manually.
- Do not store tokens in project files.
- The script opens the browser, waits for approval, and prints a session JSON payload to stdout.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The activation guidance is broad enough that the skill may trigger for general natural-language requests about business records, rather than only clearly scoped block_api tasks. Over-broad invocation increases the chance that the agent selects this skill unnecessarily and executes sensitive GraphQL reads or mutations in the wrong context.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill documentation exposes a large set of high-impact business operations for block-side records, including publish, delete, transfer, convert-to-contract, contract, invoice, and developer-profile actions. If the manifest or user expectations describe a narrower erxes scope, this mismatch can cause the agent to perform sensitive actions outside the intended permission boundary, increasing the risk of unauthorized data modification or destructive operations.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This documentation exposes destructive and state-changing GraphQL operations such as remove and merge without any warning, confirmation guidance, or rollback considerations. In an agent-skill context, that increases the chance an automated client will execute irreversible modifications on production CRM data based only on a user prompt or ambiguous instruction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The team-member invitation example includes a plaintext password in request variables, normalizing unsafe credential handling in documentation. In an agent or logged API environment, such examples can lead to passwords being stored in prompts, logs, telemetry, chat history, or tool traces, creating real credential exposure risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes the skill as managing contacts, companies, products, tags, documents, brands, automations, team members, organization data, block plugin records, and operation plugin records on an erxes instance. This file instructs the agent to operate projects, tasks, triage, teams, statuses, cycles, milestones, notes, activities, and templates, which materially expands behavior into a broad workflow/project-management domain not reflected in the manifest description.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Telling the agent that backend permissions 'should not be treated as a normal blocker' encourages behavior that disregards authorization boundaries. Even if framed as owner-mode, this weakens the agent's security posture by normalizing privileged execution assumptions instead of least privilege.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% 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 · operation-api.md (reported line 39)May include surrounding context.

md
- "Summarize project progress"
- "Find tasks with no assignee"
- "Group tasks by status"
- "Create a task for this team"
- "Create a triage item"
- "Convert this triage item to a task"
- "Show active cycles for this team"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The verification note says missing permission definitions are a backend detail and that owner-mode access should still be assumed. That guidance suppresses caution precisely where permission coverage is unclear, making accidental overreach more likely if template operations are exposed without proper controls.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/login.sh (reported line 17)May include surrounding context.

sh
# Extract subdomain from a gateway URL like https://demo.next.erxes.io/gateway -> demo
SUB=$(echo "$BASE" | sed -E 's|https?://([^./]+).*|\1|')

RESP=$(curl -sf -X POST "$BASE/oauth/device/code" \
  -H "Content-Type: application/json" \
  -H "erxes-subdomain: $SUB" \
  -d "{\"client_id\":\"$CLIENT\"}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/login.sh (reported line 39)May include surrounding context.

sh
echo "Waiting for approval..." >&2
while true; do
  sleep 5
  TOK=$(curl -s -X POST "$BASE/oauth/token" \
    -H "Content-Type: application/json" \
    -H "erxes-subdomain: $SUB" \
    -d "{\"grant_type\":\"urn:ietf:params:oauth:grant-type:device_code\",\"device_code\":\"$DC\",\"client_id\":\"$CLIENT\"}")

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file is written entirely in Mongolian, including titles, instructions, and examples, with no indication that language selection is optional or that the skill is intentionally limited to a Mongolian-speaking context. This can violate language/locale policy when a skill implicitly forces one language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The Quick Reference claims support for operations such as productDetail, productCategoriesAdd/Edit/Remove, uomsAdd/Edit/Remove, departments, branches, and various Edit/Remove mutations for organization management, but the body only documents a subset of these. This is active documentation drift: the summary table asserts specific available operations that are not actually shown elsewhere in the file.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill manifest says the skill manages block plugin records and operation plugin records, but this file only provides links to separate plugin-specific documents rather than actual GraphQL operations for those record types. Within this analyzed file, the documented behavior does not itself implement or describe those claimed management capabilities, creating a mismatch between the stated scope and the file's actual covered operations.

Content

No source excerpt is available for this finding.