Back to skill

Security audit

Sardis Openclaw

Security checks for vulnerabilities and agentic risk

Overview

This real-money payment skill is purpose-aligned, but its packaged server can forward bearer API keys to a caller-supplied URL and execute financial actions without enforcing the declared controls.

Review carefully before installing or deploying. Use only tightly scoped Sardis API keys, do not expose the included skill server without authentication, remove caller control of API destinations, require explicit human approval for payments, bridges, card issuance, and policy changes, and pin dependencies before production use.

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

T09 · Insecure Skill Coding Practices

Error
Location
src/sardis_openclaw/server.py:68
Finding

Caller-Controlled API Destination Exposes Bearer Credentials

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/sardis_openclaw/server.py:62
Finding

Declared Skill Permissions Are Not Enforced

Content
View full analysis
list[str]: """Permissions needed to execute this skill.""" ... ``` ```python # src/sardis_openclaw/skills/policy.py:22-48 @property def parameters(self) -> list[str]: return ["agent_id", "policy_rules"] @property def required_permissions(self) -> list[str]: return ["policy:write"] async def execute(self, params: dict[str, Any], context: SkillContext) -> SkillResult: err = self.validate_params(params) if err: return SkillResult(success=False, error=err) agent_id = params["agent_id"] async with httpx.AsyncClient() as client: resp = await client.put( ...[truncated 2572 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/sardis_openclaw/skills/payment.py:22
Finding

Payment Execution Omits Documented Policy, Approval, and Input Controls

Content
View full analysis
## Security Requirements **CRITICAL - ALWAYS ENFORCE:** - ALWAYS check spending policy before payment execution - NEVER bypass approval flows for transactions - NEVER hardcode wallet addresses or private keys - ALWAYS log transaction attempts for audit trail - ALWAYS verify recipient address format - FAIL CLOSED on policy violations (deny by default) ``` However, generic parameter validation checks only field presence: ```python # src/sardis_openclaw/base.py:58-63 def validate_params(self, params: dict[str, Any]) -> str | None: """Validate parameters. Returns error message or None if valid.""" missing = [p for p in self.parameters if p not in params] if missing: return f"Missing required parameters: {', '.join(missing)}" return None ``` The payment implementation submits the transaction immediately after that presence check: ```python # src/sardis_openclaw/skills/payment.py:22-51 @property def parameters(self) -> list[str]: return ["recipient", "amount", "currency", "chain"] @property def required_permissions(self) -> list[str]: return ["wallet:write", "mandate:create"] async def execute(self, params: dict[str, Any], context: SkillContext) -> SkillResult: err = self.validate_params(params) if err: return SkillResult(success=False, error=err) async with httpx.AsyncClient() as client: resp = await client.post( f"{context.base_url}/payments/send", headers={"Authorization": f"Bearer {context.api_key}"}, json={ "wallet_id": context.wallet_id, "agent_id": conte ...[truncated 2741 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
pyproject.toml:25
Finding

Security-Sensitive Dependencies Are Not Reproducibly Pinned

Content
View full analysis
=1.0.0", "httpx>=0.25.0", "pydantic>=2.6", ] ``` ```yaml # SKILL.md:18-20 install: npm: - "@sardis/sdk" ``` The nested Skill manifests use the same unversioned npm installation pattern: ```yaml install: npm: - "@sardis/sdk" ``` ### Technical Analysis Python dependencies specify only minimum versions and no upper bounds, lockfile, or hashes. The build dependency is also unpinned. The Skill metadata instructs installation of the latest resolvable `@sardis/sdk` package without a version or integrity value. As a result, two installations of the same audited project can resolve materially different dependency code. A future compromised, malicious, or incompatible release can be installed without any change to this repository. This finding does not establish that the named packages are currently malicious. The risk arises from non-reproducible and insufficiently constrained dependency resolution in a process that handles bearer credentials and financial operations. ### Attack Path 1. A permitted future dependency version is published or a dependency distribution channel is compromised. 2. A user installs or builds the project after that version becomes resolvable. 3. The package manager selects the new version because the project permits any version at or above the declared minimum, or selects the current npm release because no version is specified. 4. Installation hooks, imports, or runtime code execute with the privileges of the Skill process. 5. Compromised dependency code ...[truncated 658 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (158)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Although parts of the static finding are imprecise, the underlying security issue is real: the skill enables wallet-affecting payment execution while declaring no explicit permissions. In a money-moving skill, absence of clearly declared write scopes makes the operational trust boundary ambiguous and increases risk of accidental or unauthorized fund movement.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

Although parts of the static finding are imprecise, the underlying security issue is real: the skill enables wallet-affecting payment execution while declaring no explicit permissions. In a money-moving skill, absence of clearly declared write scopes makes the operational trust boundary ambiguous and increases risk of accidental or unauthorized fund movement.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

Although parts of the static finding are imprecise, the underlying security issue is real: the skill enables wallet-affecting payment execution while declaring no explicit permissions. In a money-moving skill, absence of clearly declared write scopes makes the operational trust boundary ambiguous and increases risk of accidental or unauthorized fund movement.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

Although parts of the static finding are imprecise, the underlying security issue is real: the skill enables wallet-affecting payment execution while declaring no explicit permissions. In a money-moving skill, absence of clearly declared write scopes makes the operational trust boundary ambiguous and increases risk of accidental or unauthorized fund movement.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

Although parts of the static finding are imprecise, the underlying security issue is real: the skill enables wallet-affecting payment execution while declaring no explicit permissions. In a money-moving skill, absence of clearly declared write scopes makes the operational trust boundary ambiguous and increases risk of accidental or unauthorized fund movement.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

Although parts of the static finding are imprecise, the underlying security issue is real: the skill enables wallet-affecting payment execution while declaring no explicit permissions. In a money-moving skill, absence of clearly declared write scopes makes the operational trust boundary ambiguous and increases risk of accidental or unauthorized fund movement.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Although parts of the static finding are imprecise, the underlying security issue is real: the skill enables wallet-affecting payment execution while declaring no explicit permissions. In a money-moving skill, absence of clearly declared write scopes makes the operational trust boundary ambiguous and increases risk of accidental or unauthorized fund movement.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · src/sardis_openclaw/skills/policy.py (reported line 1)May include surrounding context.

python
"""Policy update skill."""
from __future__ import annotations

from typing import Any

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README advertises payment execution and card issuance but does not prominently warn that these actions can move real funds or create real-world spending instruments. In an agent-skill context, this omission increases the chance that an integrator or downstream agent treats examples as low-risk automation, leading to irreversible financial actions or unintended purchases.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 29)May include surrounding context.

md
---

### 💰 [sardis-balance](./skills/sardis-balance/SKILL.md) - Read-Only Balance & Analytics

Safe, read-only skill for monitoring wallet balances and spending patterns.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 151)May include surrounding context.

md
---

### 💰 [sardis-balance](./skills/sardis-balance/SKILL.md) - Read-Only Balance & Analytics

Safe, read-only skill for monitoring wallet balances and spending patterns.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 46)May include surrounding context.

md
---

### 🛡️ [sardis-policy](./skills/sardis-policy/SKILL.md) - Spending Policy Management

Create and manage spending policies using natural language or structured rules.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 152)May include surrounding context.

md
---

### 🛡️ [sardis-policy](./skills/sardis-policy/SKILL.md) - Spending Policy Management

Create and manage spending policies using natural language or structured rules.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 63)May include surrounding context.

md
---

### 💳 [sardis-cards](./skills/sardis-cards/SKILL.md) - Virtual Card Management

Issue and manage virtual cards for real-world purchases.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 153)May include surrounding context.

md
---

### 💳 [sardis-cards](./skills/sardis-cards/SKILL.md) - Virtual Card Management

Issue and manage virtual cards for real-world purchases.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 105)May include surrounding context.

bash
# Check balance (sardis-balance)
curl -X GET https://api.sardis.sh/v2/wallets/{wallet_id}/balance \
  -H "Authorization: Bearer $SARDIS_API_KEY"

# Create policy (sardis-policy)

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This example demonstrates a live payment POST to the production API without an adjacent warning that it can move real funds and may be irreversible. In the context of an agent payment skill, providing a production-ready command so prominently increases the risk of accidental execution, especially if copied into automation or interpreted by another system as safe example behavior.

Content

Scanner excerpt · README.md (reported line 115)May include surrounding context.

md
-d '{"name": "Daily Limit", "description": "Max $500/day"}'

# Execute payment (sardis-payment)
curl -X POST https://api.sardis.sh/v2/payments \
  -H "Authorization: Bearer $SARDIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"wallet_id": "wallet_123", "to": "0x...", "amount": "25.00", "token": "USDC"}'

External Transmission

Medium
Category
Data Exfiltration
Confidence
85% confidence
Finding

The card issuance example triggers creation of a spending instrument through the production API and is shown without strong cautionary framing. In this context, an agent or user could treat the snippet as routine setup and unintentionally provision cards with real spending authority, creating financial exposure and follow-on fraud or misuse risk.

Content

Scanner excerpt · README.md (reported line 121)May include surrounding context.

md
-d '{"wallet_id": "wallet_123", "to": "0x...", "amount": "25.00", "token": "USDC"}'

# Issue virtual card (sardis-cards)
curl -X POST https://api.sardis.sh/v2/cards \
  -H "Authorization: Bearer $SARDIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "agent_123", "spending_limit": {"daily": "500.00"}}'

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

The README states policy enforcement and 'No approval flow bypassing' as principles, but it does not clearly require human approval for sensitive financial actions. In an autonomous-agent payment context, emphasizing policy-only controls can normalize unattended decision-making for money movement, which is risky if policies are broad, misconfigured, or manipulated.

Content

Scanner excerpt · README.md (reported line 160)May include surrounding context.

md
All skills enforce these security principles:

1. **Policy-First**: Always check spending policy before payment
2. **Never Bypass**: No approval flow bypassing
3. **Fail Closed**: Deny by default on policy violations
4. **Audit Everything**: Complete transaction logging
5. **Read-Only When Possible**: Use `sardis-balance` for monitoring

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill performs sensitive network operations to a payment API but declares no explicit tool scope or allowed-tools/permissions. In a payment context, missing capability scoping is dangerous because an agent can invoke outbound network actions without a clearly declared least-privilege boundary, increasing the chance of unauthorized payment, balance, or transaction-history access.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The skill requires curl, an API key, and a local config for a third-party payment service, establishing that it transmits sensitive payment-related data off-platform. External transmission is expected for this kind of integration, but in a financial skill it is inherently sensitive because wallet identifiers, transaction metadata, and authorization tokens may be exposed if invocation is not tightly controlled.

Content

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

md
- SARDIS_API_KEY
        - SARDIS_WALLET_ID
      bins:
        - curl
      config:
        - ~/.sardis/config.json
    primaryEnv: SARDIS_API_KEY

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
**CRITICAL - ALWAYS ENFORCE:**
- ALWAYS check spending policy before payment execution
- NEVER bypass approval flows for transactions
- NEVER hardcode wallet addresses or private keys
- ALWAYS log transaction attempts for audit trail
- ALWAYS verify recipient address format

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

This documented payment execution request sends wallet ID, recipient address, amount, token, chain, and purpose to an external API under a bearer token. Because it initiates fund movement, compromise or misuse could directly cause unauthorized transfers and irreversible financial impact.

Content

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

bash
# Execute a payment (policy automatically enforced)
curl -X POST https://api.sardis.sh/v2/payments \
  -H "Authorization: Bearer $SARDIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

Balance queries transmit wallet identifiers and authorization data to an external service, exposing sensitive financial metadata. While read-only, repeated or unauthorized access can leak account holdings and support targeted fraud or privacy violations.

Content

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

bash
# Get wallet balance
curl -X GET https://api.sardis.sh/v2/wallets/$SARDIS_WALLET_ID/balance \
  -H "Authorization: Bearer $SARDIS_API_KEY"

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

Policy check requests send wallet, amount, vendor, and token information to the external API, disclosing intended purchase behavior and financial controls. Although non-executing, this still exposes sensitive intent and can aid profiling or leakage of spending constraints.

Content

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

bash
# Check if payment would be allowed WITHOUT executing
curl -X POST https://api.sardis.sh/v2/policies/check \
  -H "Authorization: Bearer $SARDIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{

Static analysis

No suspicious patterns detected.