Back to skill

Security audit

Openclaw Odoo Skill

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Odoo ERP connector, but it can make live business changes and has unsafe defaults around credentials, HTTP, and webhooks that should be reviewed before installation.

Install only for an authorized Odoo environment and prefer staging first. Use a dedicated least-privilege Odoo API user, require HTTPS for any non-local Odoo server, protect and rotate API tokens, avoid committing `config.json` or `.env`, disable or lock down smart auto-create behavior where possible, and add human confirmation for orders, invoices, HR, inventory, manufacturing, deletion, and publishing actions. Do not expose the webhook publicly unless it has a strong HMAC secret, request limits, TLS, and network allowlisting. Pin installer and Python dependency versions for production use.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
odoo_skill/sync/webhook.py:36
Finding

Webhook Server Publicly Binds Without Mandatory Authentication or Request Size Limits

Content
View full analysis
None: """Handle an incoming webhook POST request.""" content_length = int(self.headers.get("Content-Length", 0)) if content_length == 0: self._respond(400, {"error": "Empty body"}) return body = self.rfile.read(content_length) # ── Signature verification ─────────────────────────────── if self.webhook_secret: signature = self.headers.get("X-Odoo-Signature", "") expected = hmac.new( self.webhook_secret.encode("utf-8"), body, hashlib.sha256, ).hexdigest() if not hmac.compare_digest(signature, expected): logger.warning("Webhook signature mismatch (remote=%s)", self.client_address[0]) self._respond(401, {"error": "Invalid signature"}) return ``` ```python def __init__( self, port: int = 8069, host: str = "0.0.0.0", secret: str = "", ) -> None: self.port = port self.host = host self.secret = secret ``` ```python def start(self) -> None: """Start the webhook server in a background thread.""" # Inject config into the handler class _WebhookHandler.webhook_secret = self.secret _WebhookHandler.callbacks = self._callbacks _WebhookHandler.default_callback = self._default_callback self._server = HTTPServer((self.host, self.port), _WebhookHandler) ``` ### Technical Analysis The webhook server binds to `0.0.0.0` by default, exposing it through every available network interface. At the same time, its shared HMAC secret defaults to an empty string. Signature verification is conditional on `self.webhook_secret`, so the def ...[truncated 2251 chars]
Remediation
View remediation
MAX_BODY_SIZE: self._respond(413, {"error": "Request body too large"}) return ``` 5. Require a timestamp and unique event identifier in signed requests, then reject stale timestamps and previously processed identifiers to prevent replay. 6. Place the server behind a TLS-enabled reverse proxy with network allowlisting and rate limiting. 7. Consider a threaded server with bounded concurrency and explicit read timeouts to reduce slow-client denial-of-service exposure. 8. Apply the same changes to the duplicated packaged implementation. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
odoo_skill/config.py:60
Finding

Odoo API Credentials and ERP Data May Be Transmitted Over Plaintext HTTP

Content
View full analysis
xmlrpc.client.ServerProxy: """``/xmlrpc/2/common`` endpoint (lazy, cached).""" if self._common is None: self._common = xmlrpc.client.ServerProxy( f"{self.config.url}/xmlrpc/2/common", allow_none=True, ) return self._common ``` ```python uid = self.common.authenticate( self.config.db, self.config.username, self.config.api_key, {}, ) ``` ```python return self.models.execute_kw( self.config.db, self.uid, self.config.api_key, model, method, list(args), kwargs if kwargs else {}, ) ``` The primary README also demonstrates a potentially remote plaintext endpoint: ```json { "url": "http://your-odoo-server:8069", "db": "your_database_name", "username": "your_email@company.com", "api_key": "your_odoo_api_key" } ``` ### Technical Analysis Configuration validation accepts both HTTP and HTTPS without distinguishing loopback development endpoints from remote network endpoints. The XML-RPC authentication request includes the database name, username, and API key. Subsequent `execute_kw` calls also include the API key and may carry sensitive ERP data. When the configured URL uses HTTP, XML-RPC traffic has no transport encryption or server authentication. A party able to observe or alter network traffic can r ...[truncated 1550 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:7
Finding

Install Instructions and Python Requirements Use Unpinned Executable Dependencies

Content
View full analysis
=1.0.0 # Testing pytest>=7.4.0 pytest-cov>=4.1.0 pytest-mock>=3.12.0 ``` The recommended installation command does not select a fixed installer version: ```bash npx clawhub install odoo-erp-connector ``` ### Technical Analysis The Python dependency declarations specify only minimum versions. A future installation can therefore resolve to any later version available from the configured package index. No lock file or cryptographic hashes are provided to verify that the downloaded artifacts match reviewed versions. Testing packages are also mixed into the main requirements file despite not being necessary for core operation, increasing the number of packages and transitive dependencies installed in production environments. The recommended `npx` invocation does not pin the `clawhub` package version. Where it is not already installed locally, `npx` can retrieve and execute a currently resolved package from the npm registry. This causes the effective installer code to change independently of the audited Skill artifact. No malicious dependency was identified in the reviewed project. The issue is that installation behavior is not reproducible and can incorporate future compromised, malicious, or incompatible upstream releases. ### Attack Path 1. A user follows the documented `npx clawhub install ...` or installs `requirements.txt`. 2. The package manager resolves current package versions rather than versions fixed during review. 3. An upstream publisher account, distribution artifact, registry, or dependency releas ...[truncated 997 chars]
Remediation
View remediation
install odoo-erp-connector ``` 6. Commit and review npm lock metadata where npm dependencies are introduced. 7. Use trusted registries, dependency scanning, artifact provenance verification, and automated update review. 8. Apply the same dependency controls to the duplicated packaged copy. ]]>
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (68)

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 72)May include surrounding context.

md
1. Log in to Odoo
2. Go to **Settings** → **Users & Companies** → **Users**
3. Open your user record
4. Scroll to **Access Tokens**
5. Click **Generate**
6. Copy the key into `config.json`

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 275)May include surrounding context.

md
1. Log in to Odoo
2. Go to **Settings** → **Users & Companies** → **Users**
3. Open your user record
4. Scroll to **Access Tokens**
5. Click **Generate**
6. Copy the key into `config.json`

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 · skills/odoo-erp-connector/README.md (reported line 74)May include surrounding context.

md
1. Log in to Odoo
2. Go to **Settings** → **Users & Companies** → **Users**
3. Open your user record
4. Scroll to **Access Tokens**
5. Click **Generate**
6. Copy the key into `config.json`

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 · skills/odoo-erp-connector/SKILL.md (reported line 275)May include surrounding context.

md
1. Log in to Odoo
2. Go to **Settings** → **Users & Companies** → **Users**
3. Open your user record
4. Scroll to **Access Tokens**
5. Click **Generate**
6. Copy the key into `config.json`

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documented fuzzy matching and automatic find-or-create workflow can silently select the wrong customer, vendor, employee, or product, or create new records when a match fails. In an ERP context this is especially dangerous because it can corrupt master data, generate fraudulent-looking transactions, misroute inventory or invoices, and cascade into accounting, procurement, HR, and manufacturing errors.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · requirements.txt (reported line 6)May include surrounding context.

text
# json — built-in Python
# http.server — built-in Python

# Optional: for .env file support
python-dotenv>=1.0.0

# Testing

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · skills/odoo-erp-connector/requirements.txt (reported line 6)May include surrounding context.

text
# json — built-in Python
# http.server — built-in Python

# Optional: for .env file support
python-dotenv>=1.0.0

# Testing

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README presents full business-control capability ('control your entire business') and broad CRUD ERP actions without prominently warning that commands may modify live records, confirm orders, create invoices, or alter HR/inventory data. In an agent skill context, this increases the chance of unsafe use, accidental destructive actions, and operator misunderstanding about the real-world consequences of natural-language commands.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The examples include direct record creation and state-changing actions such as creating quotations, leads, products, employees, expenses, and confirming orders, but they do not include cautionary notes or confirmation expectations. In a chat-driven ERP connector, copy-pasteable examples can encourage users to run live mutations against production data without understanding the operational impact.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documented fuzzy matching and automatic creation of missing customers/products can silently introduce incorrect or duplicate business entities when a name is ambiguous or misspelled. In ERP systems, unintended customer/product creation can cascade into bad quotations, inventory errors, accounting issues, and data integrity problems, making this more dangerous in context than generic auto-complete behavior.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises capabilities that inherently require network, filesystem, and environment access, but it does not declare any explicit tool scope or permission boundaries. In an agent ecosystem, missing scope declarations can cause over-privileged execution, making it easier for the skill to access secrets, modify local files, or perform unintended external actions without clear operator review.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding

The install command uses npx clawhub without a pinned version, so users may fetch and execute whatever package version is current at install time. This creates a supply-chain risk where a compromised upstream package, typo-squatted package, or breaking release could execute arbitrary code in the user's environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill is designed to create, modify, and confirm business records across sales, purchasing, inventory, HR, and accounting through natural-language commands, yet the documentation does not warn users about the consequences of autonomous state changes. In this context, silent execution of business actions can lead to financial loss, operational disruption, compliance issues, or unauthorized changes triggered by ambiguous prompts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The configuration examples instruct users to place an API key in config.json or .env but do not include warnings about secret handling, access controls, or accidental exposure. This increases the chance that operators will store long-lived credentials in plaintext, commit them to source control, or expose them through logs, backups, or world-readable files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation explicitly describes a test suite that creates, confirms, and deletes real Odoo records against a configured instance, but it does not provide a prominent warning that execution is state-changing and can affect live business data. In an ERP context, even test-created sales orders, invoices, HR records, and cleanup deletions can corrupt production workflows or remove legitimate records if configuration, naming, or cleanup logic is wrong.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The unlink method performs irreversible deletion of Odoo records, but the implementation only delegates to execute and provides no confirmation prompt or explicit user-facing warning at the point of action. Although the docstring states it deletes records, there is no runtime disclosure or safeguard for this destructive operation in this code file.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes the skill as an Odoo ERP connector for Sales, CRM, Purchase, Inventory, Projects, HR, Fleet, and Manufacturing via XML-RPC. This module also exports CalendarOps and EcommerceOps, which extend the skill beyond the explicitly described scope.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes the skill as an Odoo ERP connector for Sales, CRM, Purchase, Inventory, Projects, HR, Fleet, and Manufacturing via XML-RPC, but this file implements full CRUD operations for calendar.event. Calendar functionality is a separate capability not mentioned in the declared scope, so the actual behavior exceeds the manifest’s stated integration areas.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The mark_lost operation deactivates a CRM opportunity by setting active to False, which is a consequential state change. Although there is an internal comment and a log entry, the code does not provide a user-facing warning or confirmation that the record will be marked lost and deactivated.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring says it 'Provides read-only access to website orders and product publishing controls', which characterizes the capability as read-only. However, the implementation includes publish_product and unpublish_product methods that call client.write to change website_published on product.template records.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The code creates and updates employee records, which are direct writes to sensitive HR data, but the only disclosure present is internal logging after the action completes. There is no confirmation prompt or user-facing warning in the method docstrings/comments indicating that personal employment data will be modified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

Approving leave changes workflow state for an HR request and may have payroll or scheduling consequences. The method documents what it does, but there is no explicit warning, confirmation, or user-disclosure language indicating that it will approve a pending leave request.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

Submitting expenses for approval is a state-changing business operation, but this code only performs the action and logs it afterward. There is no confirmation prompt or user-directed warning that the listed expenses will be submitted into the approval process.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The method performs irreversible manufacturing state changes by writing qty_produced and attempting to transition the order to done with no confirmation guard, dry-run mode, or caller-visible warning. In an ERP/manufacturing context, this can prematurely consume materials, close work orders, and corrupt inventory or production records if invoked accidentally or by an over-privileged agent.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.