Back to skill

Security audit

ali-promotion-roi

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent ROI reporting tool, but it automatically approves database credential access and uses unsafe local dependency resolution, so users should review it before installing.

Install only in an environment where the sql-linker-cli database account is limited to SELECT on the two required tables, and review or remove the automatic credential approval before use. Treat JSON/report output as sensitive business data, and verify the hard-coded DBBridge import path points to a trusted, non-writable dependency location.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/roi.py:281
Finding

Unconditional Credential-Gate Approval

Content
View full analysis

Vulnerability Details

File Location: scripts/roi.py, lines 281–286
Vulnerability Type: Credential authorization bypass
Risk Level: High

python
def connect_db(user_label="openclaw-roi-analysis"):
    """连库 helper: 凭证审批闸门开启时需显式授权"""
    db = DBBridge(user_label=user_label, session_id=f"agent:main:ali-roi")
    db.explicit_credential_approval(approved=True)
    db.connect()
    return db

Technical Analysis

The database connection helper unconditionally calls explicit_credential_approval(approved=True). This programmatically asserts that credential access has been approved without obtaining a fresh authorization decision from the user or caller.

A credential gate is an access-control boundary intended to ensure that protected database credentials are released only after explicit authorization. Hard-coding the approval value makes every invocation appear approved and removes the gate's ability to distinguish authorized from unauthorized execution.

The subsequent calls in scripts/cli.py retrieve order and promotion records immediately after this connection is established:

python
db = roi.connect_db(user_label="openclaw-roi-cli")

orders = roi.fetch_orders(db, month=args.month)
promo = roi.fetch_promotion(db, month=args.month)

Attack Path

  1. An attacker, automation process, or unintended caller invokes scripts/cli.py.
  2. The CLI calls roi.connect_db().
  3. connect_db() creates a database bridge using a fixed session identifier.
  4. The code unconditionally submits approved=True to the credential gate.
  5. The bridge obtains configured database credentials and establishes a connection.
  6. The CLI queries alibaba_intl_orders and alibaba_intl_promotion_daily.
  7. The queried business data is emitted as a terminal report or JSON.

This path requires the execution environment to have a configured DBBridge and credentials capable of accessing the declared tables.

Impact Assessment

Successful exploitation gra ...[truncated 623 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the unconditional approved=True call.
  2. Make authorization an explicit input that defaults to denial.
  3. Require either an interactive user confirmation or a short-lived authorization token issued by the credential-gate system.
  4. Bind approval to the current user, operation, requested tables, and unique session rather than a fixed session identifier.
  5. Ensure headless execution fails closed when no valid approval is available.
  6. Record an audit event containing the requester, requested resources, approval source, and connection result without logging credentials.
  7. Limit the database account to SELECT access on only the two required tables.
  8. Reduce the order query to the fields actually required by the calculations, excluding unused fields such as order_no, order_currency, and buyer_country.

A safer interface would require authorization to be supplied by trusted orchestration code:

python
def connect_db(approval_token, user_label="openclaw-roi-analysis"):
    if not approval_token:
        raise PermissionError("Explicit database credential approval is required")

    db = DBBridge(
        user_label=user_label,
        session_id=create_unique_session_id(),
    )
    db.authorize_with_token(approval_token)
    db.connect()
    return db

T08 · Insecure Dependencies

Warning
Location
scripts/roi.py:39
Finding

Hard-Coded Import Path Enables Local Dependency Substitution

Content
View full analysis

Vulnerability Details

File Location: scripts/roi.py, lines 39–44
Vulnerability Type: Unsafe dependency resolution and module substitution
Risk Level: Medium

python
# sql-linker-cli 路径
SKILL_ROOT = r"C:\Users\user\.openclaw\workspace\skills\sql-linker-cli\scripts"
sys.path.insert(0, os.path.join(SKILL_ROOT, "controller_layer"))
sys.path.insert(0, os.path.join(SKILL_ROOT, "service_layer"))

from db_bridge import DBBridge  # noqa: E402

Technical Analysis

The module inserts two hard-coded local directories at the beginning of sys.path and then imports the unqualified module name db_bridge. Entries inserted at index zero take precedence over normally installed packages and most other import locations.

Python executes module-level code during import. Therefore, if an attacker can create or replace db_bridge.py in one of the preferred directories, the attacker's code executes as soon as scripts/roi.py is imported. No package qualification, version pinning, origin validation, signature verification, or integrity check is performed before import.

The hard-coded user-specific path also makes dependency behavior environment-dependent. On systems where the path is absent, the application may fail to import; on systems where the path exists and is writable by a less-trusted principal, it creates a module-substitution opportunity.

Attack Path

  1. The target environment contains the hard-coded sql-linker-cli directory structure.
  2. An attacker obtains write access to either:
    • controller_layer, or
    • service_layer.
  3. The attacker places or replaces a file named db_bridge.py in a preferred directory.
  4. A user or agent invokes scripts/cli.py.
  5. The CLI imports roi.
  6. During the roi import, the attacker-controlled directory is placed at the beginning of sys.path.
  7. Python resolves from db_bridge import DBBridge to the substituted module.
  8. The malicious module's top-level code executes with the permission ...[truncated 829 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the hard-coded user-specific dependency path and all runtime sys.path precedence modifications.
  2. Package sql-linker-cli as a normal, version-pinned Python dependency installed in an isolated virtual environment.
  3. Import DBBridge through a fully qualified package name, for example:
python
from sql_linker_cli.db_bridge import DBBridge
  1. Pin the exact dependency version and verify package hashes through the deployment lock file.
  2. Install dependencies from an authenticated, trusted package repository.
  3. Restrict dependency directories so that only the trusted deployment administrator can modify them.
  4. If dynamic loading is unavoidable, resolve the canonical module path and reject modules loaded outside an approved directory.
  5. Add startup validation that records and verifies the imported module's origin and expected version.
  6. Run the Skill under a least-privileged account so that dependency compromise has a limited impact.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The analytical purpose largely matches the description: the code is clearly for Alibaba International promotion ROI analysis using the two stated tables and computes the expected outputs such as monthly ROI, promotion-type splits, daily comparisons, and CPO. However, there is a material mismatch in how data is accessed. The description says the skill reads pre-loaded data from MySQL via sql-linker-cli and explicitly says it does NOT load data, implying ingestion is separate. In contrast, the code contains active database access helpers (connect_db, fetch_orders, fetch_promotion), imports DBBridge, establishes a live connection, explicitly approves credentials, and issues SQL queries to retrieve the data itself. That is an undeclared operational capability and inconsistent with the declared permissions being empty. So while the primary business purpose aligns, the resource-access behavior is materially under-declared.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The schema explicitly documents storage and use of buyer_name, buyer_email, and company_name, which are personal/business identifiers, but provides no privacy, minimization, masking, retention, or access-control guidance. In a skill that reads from MySQL for analysis, this increases the risk of unnecessary exposure of PII through queries, logs, outputs, or downstream handling.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill metadata says it reads pre-loaded MySQL data, but the code itself creates a DBBridge, force-enables explicit credential approval, and opens a live database connection. That bypasses an expected human approval boundary and can cause unintended access to production data or credential use when the skill is invoked.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The function explicitly calls explicit_credential_approval(approved=True) before connecting, with no user-facing confirmation or runtime check. In a skill context, this weakens the intended safety control around database credentials and can let an invocation silently access sensitive business data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file contains natural-language guidance that fixes the metric convention to CNY and explicitly contrasts it with USD. Under the policy rule, forcing a specific language/locale-style convention without opt-in or clear region-specific justification can be a violation; the document does not state that this skill is limited to a China-specific workflow or offer alternatives.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The file presents all operational documentation in Chinese and does not indicate that the language is optional, user-selectable, or required for a justified region-specific context. Under SQP-3, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This code connects to a database and retrieves order and promotion records, then prints or emits them as JSON. While the operations are part of the tool's purpose, the file itself provides no explicit warning that running the CLI will access and display potentially sensitive business data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

Replacing builtins.print affects all later code in the interpreter, not just this skill's reporting logic. That kind of process-wide runtime mutation is not justified by the stated purpose of read-only promotion ROI analysis and extends beyond ordinary analytics implementation details.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.