Back to skill

Security audit

huo15-odoo-v2

Security checks for vulnerabilities and agentic risk

Overview

The skill is an Odoo integration guide, but it persists Odoo passwords, recommends insecure TLS settings, and includes broad data-changing business operations without enough guardrails.

Install only if you expect a Chinese-language Odoo administration skill with permission to guide reads and writes against business data. Use a least-privileged, revocable Odoo account, avoid using it on production data without review, do not follow the SSL verification bypass unless you are in a controlled non-production troubleshooting case, and confirm any write, delete, bulk conversion, or activity-creation action before allowing an agent to run it.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:113
Finding

TLS Certificate and Hostname Verification Disabled for Authenticated Odoo Connections

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 113-120; repeated at lines 335-339
Vulnerability Type: Improper certificate validation
Risk Level: High

Vulnerable Code

python
# 2. SSL bypass
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

# 3. Connect
common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common', context=ctx)
uid = common.authenticate(db, user, password, {})
models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object', context=ctx)

The same insecure configuration is recommended again in the error-handling guidance:

python
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common', context=ctx)

Technical Analysis

The Skill explicitly disables both TLS certificate validation and hostname verification. TLS encryption without endpoint authentication does not establish that the client is communicating with the intended Odoo server.

The template subsequently transmits the database name, username, and reusable password through common.authenticate. Any server presenting any certificate will be accepted. Because the Odoo URL is configurable, this affects both interception of a legitimate endpoint and accidental or malicious configuration of an impostor endpoint.

Attack Path

  1. A user configures the Skill with a legitimate HTTPS Odoo URL and credentials.
  2. An attacker gains a network interception position through compromised DNS, a malicious proxy, an untrusted network, or routing manipulation.
  3. The attacker redirects the XML-RPC request to an attacker-controlled HTTPS server.
  4. The attacker presents an arbitrary or self-signed certificate.
  5. The client accepts the certificate because CERT_NONE and disabled hostname checking prevent authentication failure.
  6. The client sends the database name, username, and password to the attacker-controlled endpoint. ...[truncated 794 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove both insecure overrides:
    python
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    
  2. Use the platform trust store with certificate and hostname validation enabled:
    python
    ctx = ssl.create_default_context()
    common = xmlrpc.client.ServerProxy(
        f'{url}/xmlrpc/2/common',
        context=ctx
    )
    models = xmlrpc.client.ServerProxy(
        f'{url}/xmlrpc/2/object',
        context=ctx
    )
    
  3. Correct the Odoo server's certificate, hostname, and intermediate certificate chain rather than bypassing validation.
  4. If the deployment uses a private certificate authority, load only that trusted CA:
    python
    ctx = ssl.create_default_context(cafile='/secure/path/company-ca.pem')
    
  5. Validate the configured URL before use. Require HTTPS, reject embedded user information, and restrict the hostname to approved organizational domains where feasible.
  6. Prefer a revocable, least-privileged API credential over a reusable account password.
  7. Remove the repeated recommendation at lines 335-339 so users are not instructed to disable verification as a certificate-error workaround.
  8. Consider certificate pinning only where certificate rotation can be managed safely; do not use pinning as a replacement for basic hostname validation without an operational rotation plan.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:68
Finding

Persistent Plaintext Storage of Reusable Odoo Credentials

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 68-80
Vulnerability Type: Insecure storage of sensitive credentials
Risk Level: Medium

Vulnerable Instructions

text
🔑 Please provide your Odoo login information:

1. Username (email):
2. Password:

The Skill then directs that the submitted values be saved as follows:

text
→ Save the user input to `~/.openclaw/agents/{agentId}/odoo_creds.json`

Technical Analysis

The Skill directs the agent to persist a reusable Odoo username and password in a JSON file. No encryption, operating-system keychain integration, restrictive file permissions, ownership validation, atomic file creation, symlink protection, retention policy, or backup exclusion is specified.

JSON does not provide protection for secrets at rest. The accompanying claim that credentials are accessible only to the relevant agent is not backed by any documented access-control mechanism. The external resolver referenced elsewhere in the Skill returns the password as a normal JSON value, increasing the number of processes and memory locations through which the secret passes.

Attack Path

  1. A user initializes the Skill and supplies an Odoo username and password.
  2. The agent writes the credentials to ~/.openclaw/agents/{agentId}/odoo_creds.json.
  3. A local process, another agent operating under the same operating-system account, a compromised plugin, a backup system, or a support-collection process obtains access to that file.
  4. The actor reads the plaintext password from the JSON content.
  5. The actor authenticates to the configured Odoo service using the recovered database name, username, and password.
  6. The actor performs operations allowed by the compromised account.

If the path or parent directory can be influenced by another actor, a symlink or file-replacement attack may also redirect credential output. The current instructions do not specify controls that would prevent such behavior.

Impact

...[truncated 594 chars]

Remediation
View remediation

Remediation Suggestions

  1. Store credentials in an operating-system keychain, hardware-backed credential store, or dedicated secrets manager instead of JSON.
  2. Prefer a dedicated, revocable Odoo API credential with least-privileged permissions rather than the user's interactive account password.
  3. If file storage is unavoidable:
    • Create the file atomically with mode 0600.
    • Ensure every parent directory is owned by the expected operating-system user and is not writable by other users.
    • Reject symbolic links and validate the final resolved path.
    • Verify file ownership and permissions before every read.
    • Avoid temporary plaintext copies.
    • Exclude the credential file from source control, backups, diagnostics, and support bundles.
  4. Do not print the password or include it in logs, exception messages, command-line arguments, telemetry, or status output.
  5. Return credentials from helper processes through a protected mechanism rather than serializing the password into ordinary JSON output where possible.
  6. Add documented credential rotation, revocation, and secure deletion procedures.
  7. Update the documentation so claims about agent isolation correspond to enforceable operating-system or secret-manager access controls.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The documented connection template disables hostname verification and certificate validation, which permits man-in-the-middle interception of credentials and business data. Because this skill stores and reuses Odoo usernames and passwords, the context makes the issue more dangerous: compromised transport could expose reusable credentials and allow tampering with API responses or operations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill documents destructive and bulk business operations such as unlink, stage changes, lead conversion, and mass activity creation despite being framed as an access/configuration helper. In an agent context, such examples can normalize or enable large-scale unauthorized data modification, accidental business disruption, and irreversible record loss.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger list includes broad, common terms such as 项目, 任务, 库存, 销售, project, task, docker, and 部署, which are likely to match many unrelated conversations. This can cause unintended activation of a skill that collects or reuses Odoo connection settings and may steer users into enterprise-system actions when they did not intend to invoke this integration.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill is presented as an Odoo access/configuration guide, but it also documents broad operational capabilities including record creation, updates, deletion, and automation. That scope expansion increases the chance an agent or user will invoke high-impact actions under the assumption the skill is only for connectivity, reducing informed consent and weakening safety expectations.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill uses broad fuzzy triggers such as generic references to Odoo and related Chinese terms, making unintended invocation more likely. Because the skill contains credential handling and write/delete examples, accidental activation could expose sensitive prompts or lead users into risky operational flows without clear intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill handles credential storage and documents create/update/delete behavior without prominently warning users about data-modifying and irreversible actions. In practice this can mislead users into treating the skill as harmless setup guidance while it also enables sensitive authentication workflows and impactful business changes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The Python template invokes a local helper through subprocess, and later the file provides Docker shell commands for local environment startup. For a skill whose stated purpose is Odoo interface guidance and distributed config reuse, teaching process execution is an extra capability not clearly justified by the manifest.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest presents the skill description and initialization form entirely in Chinese, which can impose a language requirement on users without opt-in. The file does not indicate that the skill is intentionally region-specific or provide an alternative language option.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
73% confidence
Finding

The manifest description, triggers, commands, and all operational guidance are presented exclusively in Chinese, including required spoken command examples, with no indication that another language is supported or that users may opt in to this locale. Under the stated policy, forcing a specific language without user choice can be a natural-language policy violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The stated purpose is Odoo 19 interface access guidance with distributed configuration storage for reuse by other Odoo skills. The Docker local development section introduces an additional development-environment capability and shell workflow that is not justified by the manifest's narrow configuration/access description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.