Back to skill

Security audit

holded-skill

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Holded ERP skill, but it grants broad financial-system access through an unpinned third-party CLI and includes an under-scoped validation bypass for creating purchase receipts.

Install only if you trust the holdedcli source and can use a minimally scoped Holded API key. Review every write command carefully, especially receipt creation using --skip-validation, and avoid using it for non-Spanish tenants unless dates, taxes, and accounting rules are confirmed.

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 (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:4
Finding

Unpinned Holded CLI Installation from a Third-Party Homebrew Tap

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:4; references/holdedcli-reference.md:5-7
Vulnerability Type: Unpinned third-party executable dependency
Risk Level: Medium

Vulnerable Code

SKILL.md:4:

yaml
metadata: {"openclaw":{"homepage":"https://github.com/jaumecornado/holded-skill","requires":{"bins":["holded"]},"primaryEnv":"HOLDED_API_KEY","install":[{"id":"brew","kind":"brew","formula":"jaumecornado/tap/holded","bins":["holded"],"label":"Install holdedcli (brew)"}]}}

references/holdedcli-reference.md:5-7:

bash
brew tap jaumecornado/tap
brew install holded

Technical Analysis

The skill instructs users or the hosting framework to install the holded executable from the personal third-party Homebrew tap jaumecornado/tap. The dependency is not constrained to an immutable version, commit, checksum, or cryptographically verified artifact.

The installed executable occupies a sensitive trust position: it can access HOLDED_API_KEY, communicate with the Holded API, read ERP information, and execute confirmed write operations. If the tap, formula repository, release account, or referenced artifact is compromised, a modified executable could be distributed without requiring changes to this audited skill package.

This is a supply-chain weakness rather than evidence that the current upstream package is malicious.

Attack Path

  1. An attacker compromises the third-party Homebrew tap, its release infrastructure, or an artifact referenced by its formula.
  2. The attacker replaces the expected Holded CLI release with a modified executable.
  3. A user or agent follows the documented installation process:
    bash
    brew tap jaumecornado/tap
    brew install holded
    
  4. The skill invokes the compromised holded binary.
  5. The binary accesses the Holded API credential through HOLDED_API_KEY or the local Holded CLI configuration.
  6. The compromised binary c ...[truncated 872 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer an official, organization-controlled distribution channel for the Holded CLI.
  2. Pin installation to a reviewed, immutable release rather than implicitly installing the latest formula.
  3. Verify downloaded artifacts using a published SHA-256 digest or cryptographic release signature.
  4. Pin the tap or formula to a reviewed commit where the deployment mechanism permits it.
  5. Add installation documentation identifying the expected source repository, release version, and checksum.
  6. Use a Holded API key restricted to the minimum entities and operations required by the skill.
  7. Rotate the API key immediately if dependency or release-infrastructure compromise is suspected.
  8. Where possible, execute the CLI in a restricted environment with limited filesystem and network access.

T09 · Insecure Skill Coding Practices

Note
Location
SKILL.md:102
Finding

Client-Side Schema Validation Is Disabled for Financial-Document Creation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:36-37, SKILL.md:68-69, and SKILL.md:102-112
Vulnerability Type: Unsafe validation bypass on accounting write operations
Risk Level: Low

Vulnerable Code

SKILL.md:102-112:

bash
Purchase receipt rule (mandatory for purchase tickets):

```bash
holded actions describe invoice.create-document --json
holded actions run invoice.create-document \
  --path docType=purchase \
  --body '{"isReceipt": true, "date": 1770764400, "contactId": "<contactId>", "items": [{"name": "Description", "units": 1, "subtotal": 29.4, "tax": 0}]}' \
  --skip-validation \
  --json
text

The mandatory instruction at `SKILL.md:36-37` states:

```text
For purchase receipts, always enforce `docType=purchase` and include `"isReceipt": true` in the JSON body. Since holdedcli validates against Holded's schema (which doesn't include `isReceipt`), you **must** use `--skip-validation` flag.

Technical Analysis

The workflow intentionally disables the CLI's schema validation for purchase-receipt creation because the required isReceipt property is not represented in the CLI's Holded schema. The --skip-validation option is applied to the entire request body rather than only permitting the single known extension.

As a result, malformed types, misspelled fields, unsupported properties, or semantically invalid item data may not be detected by the CLI before submission. The mandatory user-confirmation process reduces accidental execution but does not provide structural or semantic validation of the payload.

Exploitation depends on the Holded API accepting data that the CLI would otherwise reject. If server-side validation is comprehensive, the API may reject the request and reduce the practical impact.

Attack Path

  1. A purchase-receipt payload is generated with malformed, manipulated, or unintended fields.
  2. The workflow adds --skip-validation because `i ...[truncated 1067 chars]
Remediation
View remediation

Remediation Suggestions

  1. Update the Holded CLI schema so that isReceipt is explicitly supported for the applicable document-creation action.
  2. Avoid using a general-purpose --skip-validation option once the upstream schema is corrected.
  3. Until then, define a narrow local schema for purchase receipts and validate the complete payload before invoking the CLI.
  4. Permit only the known isReceipt extension while validating all other fields, types, ranges, and required properties.
  5. Validate financial constraints such as nonnegative units and subtotals, permitted tax values, valid contact identifiers, and timestamps expressed in seconds.
  6. Reject unexpected additional properties rather than forwarding them to the API.
  7. Present a normalized payload and calculated totals during confirmation so the user can review the actual accounting effect.
  8. Add tests covering malformed JSON, incorrect field types, unsupported tax values, missing contact IDs, and unintended extra properties.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

The skill explicitly instructs use of --skip-validation for purchase receipts, which disables client-side schema validation for a write operation. Bypassing validation weakens a key safety control and can allow malformed, unintended, or manipulated fields to reach the API, increasing the risk of bad accounting records or abusive payload construction.

Content

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

md
- Treat any `POST`, `PUT`, `PATCH`, or `DELETE` action as **write**.
- Treat any `GET` action (or `HEAD` when present) as **read**.
- Before any operation, always run `holded actions describe <action> --json` (after `holded actions list`) to validate accepted parameters.
- For purchase receipts, always enforce `docType=purchase` and include `"isReceipt": true` in the JSON body. Since holdedcli validates against Holded's schema (which doesn't include `isReceipt`), you **must** use `--skip-validation` flag.
- Ask for explicit user confirmation **every time** before any write action.
- Do not execute writes on ambiguous replies (`ok`, `go ahead`, `continue`) without clarification.
- Repeat the exact command before confirmation to avoid unintended changes.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

This workflow normalizes a validation bypass as part of the standard write path for purchase receipts. Making schema bypass part of routine execution increases the chance that unsafe or attacker-influenced parameters are sent during document creation, despite the presence of confirmation prompts.

Content

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

md
1. Locate and validate the action.
2. Run `holded actions describe <action> --json` to verify required/optional parameters.
3. Prepare the final payload.
4. If creating a purchase receipt/ticket, verify `docType=purchase` and `"isReceipt": true`, and use `--skip-validation` flag.
5. Request mandatory confirmation.
6. Run the command after confirmation.
7. Report result (`status_code`, affected ID, API response).

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The example command directly demonstrates a write action using --skip-validation, making unsafe execution easy to copy verbatim. Concrete examples strongly shape agent behavior, so this increases the likelihood that validation is bypassed in production rather than treated as a rare exception.

Content

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

holded actions run invoice.create-document
--path docType=purchase
--body '{"isReceipt": true, "date": 1770764400, "contactId": "", "items": [{"name": "Description", "units": 1, "subtotal": 29.4, "tax": 0}]}'
--skip-validation
--json

text

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The notes justify --skip-validation as necessary because the schema lacks isReceipt, effectively instructing the agent to defeat a safety mechanism whenever this case appears. In a financial system integration, habitual validation bypass materially raises the risk of unintended writes, malformed accounting data, and exploitation via crafted payloads.

Content

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

text

**Important notes:**
- Use `--skip-validation` flag because holdedcli validates against Holded's schema which doesn't include `isReceipt`.
- Use `subtotal` in items (not `price`) - this is the field name Holded's API expects.
- Timestamps must be in seconds (Unix epoch) and in **Europe/Madrid timezone**.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill description is broad enough to match many common ERP-related requests, including destructive operations across contacts, invoices, accounting, and generic API endpoints. In an agentic environment, overly broad routing increases the chance the skill is invoked in situations where the user intent is underspecified, leading to unintended data access or modification.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
93% confidence
Finding

The skill establishes skip-validation as a required default behavior for a class of write operations, which is an unsafe default because it lowers the protection baseline without case-by-case risk evaluation. Even with user confirmation, agents may treat the bypass as routine and fail to detect malformed or risky payloads.

Content

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

md
- Treat any `POST`, `PUT`, `PATCH`, or `DELETE` action as **write**.
- Treat any `GET` action (or `HEAD` when present) as **read**.
- Before any operation, always run `holded actions describe <action> --json` (after `holded actions list`) to validate accepted parameters.
- For purchase receipts, always enforce `docType=purchase` and include `"isReceipt": true` in the JSON body. Since holdedcli validates against Holded's schema (which doesn't include `isReceipt`), you **must** use `--skip-validation` flag.
- Ask for explicit user confirmation **every time** before any write action.
- Do not execute writes on ambiguous replies (`ok`, `go ahead`, `continue`) without clarification.
- Repeat the exact command before confirmation to avoid unintended changes.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
92% confidence
Finding

Embedding skip-validation in the canonical write procedure creates an insecure operational default for receipt creation. This is particularly concerning in an ERP/accounting context, where data integrity and schema correctness are core safeguards against erroneous or unauthorized financial records.

Content

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

md
1. Locate and validate the action.
2. Run `holded actions describe <action> --json` to verify required/optional parameters.
3. Prepare the final payload.
4. If creating a purchase receipt/ticket, verify `docType=purchase` and `"isReceipt": true`, and use `--skip-validation` flag.
5. Request mandatory confirmation.
6. Run the command after confirmation.
7. Report result (`status_code`, affected ID, API response).

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
94% confidence
Finding

The sample command operationalizes an unsafe default by presenting validation bypass as the standard example for document creation. Users and agents often mirror examples, so the presence of this command increases systemic misuse of the unsafe flag.

Content

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

holded actions run invoice.create-document
--path docType=purchase
--body '{"isReceipt": true, "date": 1770764400, "contactId": "", "items": [{"name": "Description", "units": 1, "subtotal": 29.4, "tax": 0}]}'
--skip-validation
--json

text

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
92% confidence
Finding

The documentation text normalizes a validation bypass as expected behavior, reducing operator skepticism toward weakened safeguards. In a tool that can create accounting documents, unsafe defaults are more dangerous because errors propagate into financial and tax records.

Content

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

text

**Important notes:**
- Use `--skip-validation` flag because holdedcli validates against Holded's schema which doesn't include `isReceipt`.
- Use `subtotal` in items (not `price`) - this is the field name Holded's API expects.
- Timestamps must be in seconds (Unix epoch) and in **Europe/Madrid timezone**.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Mandating Europe/Madrid timestamps without checking the user's locale or company settings can cause accounting entries to be recorded on the wrong date or period. In ERP and tax workflows, timezone errors can materially affect invoices, receipts, and reporting, especially around midnight, DST transitions, or multinational usage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file documents passing the Holded API key via command-line flag, environment variable, and config file, which are sensitive credential-handling paths. While it explains where credentials can be supplied, it does not warn users about exposure risks such as shell history, plaintext config storage, or safeguarding the API key.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The config example explicitly normalizes storing an API key in plaintext in application configuration. In a skill whose purpose is to operate an ERP with read/write/delete capabilities, encouraging plaintext secret placement increases the likelihood of credential leakage through source control, backups, logs, screenshots, or local compromise, which could enable unauthorized access to sensitive business data and destructive actions.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.