Back to skill

Security audit

QStrader - AI Trading Assistant

Security checks for vulnerabilities and agentic risk

Overview

This is a real broker-connected trading skill with disclosed trading behavior, but it publishes an unauthenticated trading endpoint and relies on weak procedural safety controls for potentially live orders.

Review this carefully before installing. Use only a demo or tightly limited broker account unless the MCP server has real authentication, per-operation authorization, and server-side confirmation for every trade. Rotate the published endpoint if it is live, avoid sourcing untrusted .env files, and do not rely on the included risk_manager.py as a hard financial safety control without fixing and testing its loss-limit logic.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/mcp-endpoints.md:5
Finding
Hard-Coded Unauthenticated MCP Trading Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `references/mcp-endpoints.md:5-6` **Vulnerability Type**: Exposed unauthenticated trading control endpoint **Risk Level**: High ### Vulnerable Code ```text URL: `https://nnn8-antonbustrov.amvera.io/mcp/acc6ad15-3e20-4d20-9094-85bbb12e0780` Auth: none ``` The same document identifies broker write operations, including `Place_Order`, `Close_an_open_deal`, `Modify_Order`, and stop-loss/take-profit modification. ### Technical Analysis The Skill publishes a concrete MCP endpoint and explicitly states that authentication is not required. The endpoint is associated with both sensitive account-information operations and broker write operations. The workflow identifier embedded in the URL may function as a bearer-like capability. Even if the server implements controls not visible in this repository, publishing the complete endpoint unnecessarily expands the attack surface and violates least-privilege principles. Client-side instructions requiring user confirmation do not provide an authorization boundary: a caller interacting directly with the MCP service can attempt to bypass those instructions. The trading functionality legitimately requires access to a broker gateway, but it does not require distributing a specific unauthenticated deployment URL with the Skill. ### Attack Path 1. An attacker obtains the Skill package or reads the public reference document. 2. The attacker extracts the hard-coded MCP endpoint. 3. The attacker connects to the endpoint without presenting credentials. 4. The attacker enumerates or invokes exposed MCP tools. 5. If server-side authorization is absent as documented, the attacker reads account information or attempts broker write operations directly, without the Skill's user-confirmation workflow. ### Impact Assessment A successful exploit could expose account balances, margin information, open deals, and order history. If write operations are reachable without independent serve ...[truncated 269 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the concrete deployment URL from the repository and replace it with a placeholder. 2. Rotate the exposed workflow identifier and invalidate the existing endpoint. 3. Require strong authentication, such as short-lived OAuth tokens or mutually authenticated TLS. 4. Enforce authorization on the MCP server for every operation, particularly broker write operations. 5. Separate read-only market-data tools from account and trading tools using distinct credentials and service identities. 6. Apply network allowlists, rate limiting, audit logging, and anomaly detection. 7. Require server-side transaction confirmation or approval for order placement, modification, cancellation, and closure. 8. Never rely on agent instructions such as “only with user confirmation” as the sole access-control mechanism. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/risk_manager.py:169
Finding
Documented Hard Position-Loss Limit Fails Open<![CDATA[ ## Vulnerability Details **File Location**: `scripts/risk_manager.py:169-173` **Vulnerability Type**: Fail-open financial risk validation **Risk Level**: High ### Vulnerable Code ```python if position_loss > MAX_POSITION_LOSS: warnings.append( f"⚠️ Потенциальный убыток ${position_loss:.0f} > лимит ${MAX_POSITION_LOSS}. " "Уменьши объём или подтяни SL." ) approved = len(errors) == 0 ``` ### Technical Analysis `MAX_POSITION_LOSS` is documented as a hard limit, but exceeding it only adds a warning. Approval depends exclusively on whether `errors` is empty. Consequently, a trade with a calculated potential loss above the configured maximum can still return: ```json {"approved": true} ``` The check also calculates loss as `abs(price - stop_loss) * volume`, which does not account for contract size, tick value, quote currency conversion, commissions, leverage, or instrument-specific rules. This may materially underestimate exposure. In addition, the implementation does not enforce the documented minimum reward-to-risk ratio of 2:1 and does not verify that stop-loss and take-profit values are on the correct side of the entry price. ### Attack Path 1. A caller supplies a large volume or a stop loss far from the entry price. 2. The calculated `position_loss` exceeds `MAX_POSITION_LOSS`. 3. The script records only a warning rather than an error. 4. No other validation error is generated. 5. `approved` is set to `True`. 6. An agent or downstream workflow treats the successful exit status and approval result as authorization to proceed with the trade. ### Impact Assessment The flaw does not grant operating-system privileges. Its impact is within the connected trading account: orders that violate the stated maximum-loss policy may be approved and subsequently submitted. Depending on instrument contract size and leverage, the actual loss can substantially exceed both the displayed estimate and the configured `$100` limit. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add an error, rather than a warning, whenever `position_loss > MAX_POSITION_LOSS`. 2. Reject trades when exposure cannot be calculated reliably. 3. Retrieve trusted instrument metadata, including contract size, tick size, tick value, quote currency, leverage, and minimum volume. 4. Calculate worst-case loss using broker-consistent valuation and currency conversion. 5. Enforce stop-loss direction: - Buy: stop loss below entry. - Sell: stop loss above entry. 6. Enforce take-profit direction and a reward-to-risk ratio of at least 2:1. 7. Make warnings non-approvable unless a separately authenticated override process exists. 8. Add unit and integration tests proving that every documented hard-limit violation returns `approved: false` and a nonzero process exit status. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/risk_manager.py:149
Finding
Daily-Loss Control Uses Current Equity Drawdown Instead of Daily P&amp;L<![CDATA[ ## Vulnerability Details **File Location**: `scripts/risk_manager.py:149-163` **Vulnerability Type**: Incorrect daily-loss calculation **Risk Level**: High ### Vulnerable Code ```python if equity < balance: daily_loss_pct = (balance - equity) / balance max_loss_usd = balance * MAX_DAILY_LOSS current_loss_usd = balance - equity if daily_loss_pct >= MAX_DAILY_LOSS: errors.append( f"❌ Дневной убыток {daily_loss_pct:.1%} (${current_loss_usd:.0f}) >= {MAX_DAILY_LOSS:.0%} " f"(${max_loss_usd:.0f}). СТОП ТОРГОВЛИ НА ДЕНЬ!" ) elif daily_loss_pct >= MAX_DAILY_LOSS * 0.8: warnings.append( f"⚠️ Дневной убыток {daily_loss_pct:.1%} — близко к лимиту {MAX_DAILY_LOSS:.0%}" ) ``` ### Technical Analysis The calculation `(balance - equity) / balance` measures current unrealized drawdown relative to the current balance. It does not measure total loss since the beginning of the trading day. Once a losing position is closed, its loss is reflected in the new balance. Equity may then become approximately equal to that lower balance, causing the calculated “daily loss” to return to zero. Repeated realized losses can therefore evade the documented 2% daily stop. The implementation does not retrieve a start-of-day balance or equity snapshot and does not aggregate realized and unrealized daily profit and loss. ### Attack Path 1. The account begins the day with a known equity value. 2. A position incurs a loss. 3. The losing position is closed, realizing the loss and reducing the account balance. 4. Current equity becomes approximately equal to the newly reduced balance. 5. The script calculates `(balance - equity) / balance`, producing a value near zero. 6. The risk check approves additional trades even though cumulative daily losses may already exceed 2%. 7. The process can repeat, allowing cumulative losses to grow beyond the stated daily limit. ### Impact Assessment The affected ...[truncated 354 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Record a trusted start-of-day equity value using the broker's trading-day timezone. 2. Calculate daily loss as cumulative realized P&amp;L plus current unrealized P&amp;L relative to start-of-day equity. 3. Prefer broker-provided daily P&amp;L data where available. 4. Persist the daily baseline in a protected store that callers cannot arbitrarily overwrite. 5. Handle deposits, withdrawals, fees, financing costs, and currency conversions separately. 6. Fail closed when the baseline or current account data is unavailable. 7. Reset the baseline only at the defined trading-day boundary. 8. Add tests covering realized losses, unrealized losses, partial closures, multiple trades, and day-boundary transitions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup.sh:28
Finding
Arbitrary Shell Execution Through Sourced Environment File<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:28` **Vulnerability Type**: Shell command execution through configuration parsing **Risk Level**: Medium ### Vulnerable Code ```bash set -a; source "$SKILL_DIR/.env"; set +a ``` ### Technical Analysis Bash `source` treats the target file as executable shell syntax, not as a passive key-value configuration file. An `.env` file can therefore contain command substitutions, redirects, function definitions, or arbitrary commands that execute with the privileges of the user running `setup.sh`. The setup documentation encourages users to create and edit this file. If the file, its template, or the Skill directory is modified by an untrusted party, running setup becomes a local code-execution vector. The script only requires a small allowlist of configuration values. Executing unrestricted shell syntax therefore exceeds the minimum privileges necessary to load the configuration. ### Attack Path 1. An attacker gains the ability to modify `.env` or distribute a malicious `.env.example`. 2. The attacker inserts shell commands or command substitution into the file. 3. A user runs `bash scripts/setup.sh`. 4. Bash executes the malicious content when the script reaches `source "$SKILL_DIR/.env"`. 5. The payload runs with the user's permissions and can access files and credentials available to that user. ### Impact Assessment Successful exploitation provides arbitrary command execution as the user running the setup script. This can expose OpenClaw configuration, MCP credentials, broker endpoint information, API keys, and other user-accessible files. If the user runs setup with elevated privileges, the impact expands to those elevated privileges, although the supplied instructions do not require elevation. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not use `source` to parse `.env` files. 2. Parse only an explicit allowlist of expected keys, such as `N8N_MCP_URL`, `QDRANT_URL`, and required credentials. 3. Reject malformed lines, duplicate keys, shell metacharacters, command substitutions, and unexpected variable names. 4. Use a dedicated configuration parser or a structured format such as JSON with strict schema validation. 5. Require restrictive permissions, such as mode `0600`, for files containing secrets. 6. Verify that the configuration file and parent directory are owned by the expected user and are not writable by other users. 7. Never instruct users to run the setup script with elevated privileges. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/setup.sh:33
Finding
Unpinned Global Package Installation and Execution Guidance<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:33-35` **Vulnerability Type**: Unsafe third-party dependency installation guidance **Risk Level**: Medium ### Vulnerable Code ```bash if ! command -v mcporter &>/dev/null; then echo "❌ mcporter не установлен." echo " Установите: npm install -g mcporter" echo " Или: npx mcporter ..." ``` ### Technical Analysis The setup output recommends globally installing or directly executing `mcporter` without a pinned version, lockfile, integrity hash, or verified source. `npm install -g mcporter` resolves the current registry version at installation time, while `npx mcporter` may download and execute a package dynamically. This creates dependency drift and supply-chain risk. A compromised package release, registry account, or package-resolution path could result in unexpected code executing during installation or invocation. Although the script prints these commands rather than executing them automatically, users are explicitly directed to run them as part of setup. ### Attack Path 1. An attacker compromises the relevant package, publisher account, or package distribution path. 2. A user runs the unpinned command recommended by the setup script. 3. npm resolves the attacker-controlled or compromised current package version. 4. Installation scripts or the package executable run with the user's permissions. 5. The malicious package accesses local files, environment variables, MCP configuration, or other user resources. ### Impact Assessment A compromised dependency could execute arbitrary code as the installing user. A global installation can also affect other projects and sessions that invoke the same command. Potentially exposed resources include OpenClaw workspace files, API keys, MCP configuration, and any broker-related credentials available to the user. Exploitation depends on compromise or substitution of the external dependency. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `mcporter` to a specifically reviewed version. 2. Document the authoritative package name, publisher, repository, and expected integrity information. 3. Use a project-local dependency with a lockfile instead of an unrestricted global installation. 4. Use reproducible installation commands such as `npm ci` with committed integrity metadata. 5. Avoid `npx` behavior that downloads an unspecified latest package at runtime. 6. Review package lifecycle scripts and disable them where they are unnecessary. 7. Establish a controlled dependency-update process with security review and automated vulnerability scanning. ]]>
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
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (38)

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding
The declared description presents a broad automated trading assistant with multiple operational capabilities, including execution and risk workflows. The supplied code chunk has a much narrower purpose: market analysis for a ticker using technical analysis and LSTM prediction, plus fetching account data as context. While this partially aligns with the 'market analysis' aspect of the description and does use an MCP-connected workflow, the code does not substantiate most of the described assistant functionality. This is a description-to-behavior mismatch because the actual implemented behavior is materially narrower than the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description presents a full-featured automated trading assistant with analysis, risk controls, execution, monitoring, and journaling. The supplied code only implements one narrow function: trade journaling/logging. While trade journaling is mentioned in the description, the primary purpose and capabilities of the code chunk are far more limited than the declared skill. There is no evidence of market analysis, position management, portfolio monitoring, news handling, or broker-backed trade execution. The code accesses a Qdrant journaling endpoint through mcporter, which is materially different from the described n8n MCP-based automated hedge fund behavior.

Credential Access

High
Category
Privilege Escalation
Content
```bash
cd skills/qstrader
cp .env.example .env  # Заполнить свои ключи
bash scripts/setup.sh
```
Confidence
89% confidence
Finding
The setup instructions explicitly direct creation and population of a .env file containing user keys. In a skill that also relies on shell access and broker-connected tooling, this increases the risk that secrets are stored locally in plaintext and later exposed through logs, shell commands, mis-scoped tools, or accidental repository inclusion.

Credential Access

High
Category
Privilege Escalation
Content
echo "🔶 QStrader Setup"
echo "=================="

# 1. Проверка .env
if [ ! -f "$SKILL_DIR/.env" ]; then
    if [ -f "$SKILL_DIR/.env.example" ]; then
        cp "$SKILL_DIR/.env.example" "$SKILL_DIR/.env"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
echo "🔶 QStrader Setup"
echo "=================="

# 1. Проверка .env
if [ ! -f "$SKILL_DIR/.env" ]; then
    if [ -f "$SKILL_DIR/.env.example" ]; then
        cp "$SKILL_DIR/.env.example" "$SKILL_DIR/.env"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
echo "🔶 QStrader Setup"
echo "=================="

# 1. Проверка .env
if [ ! -f "$SKILL_DIR/.env" ]; then
    if [ -f "$SKILL_DIR/.env.example" ]; then
        cp "$SKILL_DIR/.env.example" "$SKILL_DIR/.env"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
echo "=================="

# 1. Проверка .env
if [ ! -f "$SKILL_DIR/.env" ]; then
    if [ -f "$SKILL_DIR/.env.example" ]; then
        cp "$SKILL_DIR/.env.example" "$SKILL_DIR/.env"
        echo "✅ Создан .env из шаблона. Заполните свои ключи:"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
echo "=================="

# 1. Проверка .env
if [ ! -f "$SKILL_DIR/.env" ]; then
    if [ -f "$SKILL_DIR/.env.example" ]; then
        cp "$SKILL_DIR/.env.example" "$SKILL_DIR/.env"
        echo "✅ Создан .env из шаблона. Заполните свои ключи:"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
echo "=================="

# 1. Проверка .env
if [ ! -f "$SKILL_DIR/.env" ]; then
    if [ -f "$SKILL_DIR/.env.example" ]; then
        cp "$SKILL_DIR/.env.example" "$SKILL_DIR/.env"
        echo "✅ Создан .env из шаблона. Заполните свои ключи:"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
echo "=================="

# 1. Проверка .env
if [ ! -f "$SKILL_DIR/.env" ]; then
    if [ -f "$SKILL_DIR/.env.example" ]; then
        cp "$SKILL_DIR/.env.example" "$SKILL_DIR/.env"
        echo "✅ Создан .env из шаблона. Заполните свои ключи:"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
echo "=================="

# 1. Проверка .env
if [ ! -f "$SKILL_DIR/.env" ]; then
    if [ -f "$SKILL_DIR/.env.example" ]; then
        cp "$SKILL_DIR/.env.example" "$SKILL_DIR/.env"
        echo "✅ Создан .env из шаблона. Заполните свои ключи:"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
exit 1
    fi
fi
echo "✅ .env найден"

# Загрузить переменные
set -a; source "$SKILL_DIR/.env"; set +a
Confidence
94% confidence
Finding
`source "$SKILL_DIR/.env"` executes the `.env` file as shell code, not just parses key-value pairs. If the `.env` file is maliciously modified or contains shell substitutions/commands, running setup will execute arbitrary code in the user's environment; in a trading skill with broker-connected infrastructure, that could enable credential theft, system compromise, or unauthorized trading actions.

Credential Access

High
Category
Privilege Escalation
Content
TEST_RESULT=$(mcporter call my-n8n-mcp.Get_account_data 2>&1 || echo "FAILED")
if echo "$TEST_RESULT" | grep -q "error\|FAILED\|ECONNR"; then
    echo "❌ Не удалось подключиться к n8n MCP"
    echo "   Проверьте N8N_MCP_URL в .env"
    echo "   Ответ: $TEST_RESULT" | head -5
else
    echo "✅ Подключение успешно!"
Confidence
77% confidence
Finding
On failure, the script prints `TEST_RESULT`, which may include server responses, identifiers, or sensitive account-related error details returned by `Get_account_data`. In the context of a trading assistant wired to broker-accessible MCP infrastructure, verbose output can leak operational or financial metadata into terminal history, logs, CI output, or shared support captures.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The natural-language instructions and usage documentation are presented in Russian throughout the file, but the README does not indicate that the user can choose another language or that the locale restriction is intentional and justified. This can violate language/locale policy when a skill effectively forces one language without opt-in.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# Если у тебя .skill файл:
mkdir -p ~/.openclaw/workspace/skills/qstrader
tar -xzf qstrader.skill -C ~/.openclaw/workspace/skills/

# Или скопировать папку qstrader/ в skills/
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.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# Ecли y тe6я .skill фaйл:
mkdir -p ~/.openclaw/workspace/skills/qstrader
tar -xzf qstrader.skill -C ~/.openclaw/workspace/skills/

# Или cкoпиpoвaть пaпкy qstrader/ в skills/
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.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The README says the agent will request human confirmation before placing orders, but this is described only as policy text and not as an enforced control. In a trading skill with direct broker write endpoints, a non-enforced confirmation step can be bypassed by agent behavior, prompt errors, or integration mistakes, leading to unauthorized live trades.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The skill is described as activating automatically and handling analysis, risk checks, confirmations, and logging based on broad natural-language requests. In the context of broker-connected automation, vague activation boundaries increase the chance of accidental invocation of sensitive workflows, including trade preparation or execution paths.

Context-Inappropriate Capability

Medium
Confidence
85% confidence
Finding
The README exposes `register_new_user` and `get_access_token` endpoints as part of a trading skill even though they are not necessary for the stated market-analysis and trade-execution workflow. Unrelated auth/account endpoints expand the accessible attack surface and may let an agent or operator invoke identity or token flows that were not intended for this skill.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documents use of shell commands, environment files, and broker-connected MCP operations, but does not declare any tool restrictions such as allowed-tools or permissions. In a trading skill, missing scope boundaries is dangerous because an agent may be granted broader shell/env access than necessary and could reach credentials or execute unintended commands during setup or trade workflows.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This markdown file presents the skill title, workflows, and safety instructions entirely in Russian, which can force a specific language on users. The policy allows locale constraints only when they are explicitly justified or when users are given a language/locale choice, neither of which is stated here.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The skill states that any order requires user confirmation, yet later provides direct trade placement commands in the documented workflow. In the context of a broker-connected trading assistant, this inconsistency can lead an agent or operator to place real orders without a reliable confirmation control, creating immediate financial-loss risk.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
The title and all operational instructions are presented in Russian, with no indication that another language is supported or that the user can opt into this locale. Under the policy, forcing a specific language without user choice is a natural-language policy violation unless clearly justified as region-specific.

Static analysis

No suspicious patterns detected.