Back to skill

Security audit

settlement-witness

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed local receipt verifier with optional, user-initiated DefaultVerifier network workflows, not hidden or automatic data transfer.

Install only if you are comfortable with two unpinned Python dependencies and understand that local verification is offline by default. Use remote issuance only when you intentionally want to send the provided task_id, spec, and output to DefaultVerifier, and avoid sending sensitive outputs. Treat valid:true primarily as cryptographic verification unless the schema-validation gap is fixed or independently checked.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/verify_receipt.py:180
Finding

Incomplete SAR v0.1 Receipt Schema Validation

Content
View full analysis

Vulnerability Details

File Location: scripts/verify_receipt.py, lines 180-196
Vulnerability Type: Incomplete input and protocol validation
Risk Level: Medium

Vulnerable Code

python
sig = receipt.get("sig")

# Structural / prefix rules (ported from _sar_verify_receipt_v0_1).
if not (isinstance(rid, str) and rid.startswith("sha256:")):
    errors.append("receipt_id missing required 'sha256:' prefix")
if not (isinstance(sig, str) and sig.startswith("base64url:")):
    errors.append("sig missing required 'base64url:' prefix")
if not (isinstance(kid, str) and kid.strip()):
    errors.append("verifier_kid missing")
for field in _CORE_REQUIRED:
    if receipt.get(field) is None:
        errors.append(f"missing required core field: {field}")
if errors:
    return result()

Technical Analysis

The verifier checks whether required core fields are present, but it does not enforce the complete receipt schema documented in spec/canonicalization.md.

In particular, it does not validate:

  • That sar_version is present and exactly identifies the supported protocol version.
  • That verdict is one of PASS, FAIL, or INDETERMINATE.
  • The documented types of task_id_hash, confidence, reason_code, and ts.
  • The allowed range and finiteness of confidence.
  • That task_id_hash and receipt_id contain correctly formed, fixed-length SHA-256 hexadecimal values.
  • That ts is a valid ISO 8601 UTC timestamp.
  • Any defined constraints on reason_code.

Cryptographic verification only establishes that the selected fields were signed by the corresponding private key. It does not establish that those fields conform to SAR v0.1. Consequently, a correctly signed but semantically malformed receipt can be returned with valid: true.

This conflicts with the claim in SECURITY.md that a valid result means the receipt structure satisfies SAR v0.1 field and prefix expectations. Do ...[truncated 1766 chars]

Remediation
View remediation

Remediation Suggestions

Implement strict schema validation before canonicalization and signature acceptance:

  1. Require sar_version and reject any value other than the explicitly supported version.
  2. Enforce exact JSON types for every signed field. In Python, explicitly reject booleans where a numeric value is expected because bool is a subclass of int.
  3. Restrict verdict to PASS, FAIL, or INDETERMINATE.
  4. Validate confidence as a finite numeric value within the protocol-defined range.
  5. Validate SHA-256 identifiers using an exact expression such as ^sha256:[0-9a-f]{64}$.
  6. Parse ts and require the protocol-defined ISO 8601 UTC representation.
  7. Enforce the permitted reason_code values or format.
  8. Validate optional counterparty values consistently rather than silently excluding invalid types from the signed core.
  9. Distinguish cryptographic authenticity from schema validity in the result, for example with separate signature_valid and schema_valid fields.
  10. Add negative tests for wrong versions, unknown verdicts, malformed hashes, invalid timestamps, non-finite numbers, incorrect JSON types, and out-of-range confidence values.

T08 · Insecure Dependencies

Note
Location
SKILL.md:12
Finding

Unpinned Runtime Verification Dependencies

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 12-17
Vulnerability Type: Non-reproducible dependency installation and supply-chain exposure
Risk Level: Low

Vulnerable Code

yaml
install:
  - kind: uv
    package: jcs
  - kind: uv
    package: cryptography

Technical Analysis

The Skill installs jcs and cryptography without exact version constraints or artifact hashes. Installation therefore resolves mutable package versions from the configured package index at installation time.

These packages execute within the verifier's Python process and are directly involved in canonicalization and Ed25519 signature verification. A compromised, malicious, or incompatible future release could execute code during installation or runtime, alter canonicalization behavior, weaken verification, or access data available to the process.

No evidence was found that the named packages are currently malicious. The issue is the absence of reproducible dependency controls rather than a demonstrated compromise or typosquatted dependency.

Attack Path

  1. A dependency release, package-index account, distribution artifact, or configured package source is compromised.
  2. The attacker publishes or substitutes a malicious version under one of the unpinned package names.
  3. A user installs the Skill after the malicious version becomes the version selected by the resolver.
  4. The installer downloads and installs the attacker-controlled artifact because no exact version or hash is enforced.
  5. Malicious package code executes during installation, import, canonicalization, or signature verification.
  6. The code gains the privileges and data access of the user or agent process running the installation or verifier.

Impact Assessment

Successful exploitation could execute arbitrary Python code with the privileges of the installing or verifying process. Depending on the host environment, that could per ...[truncated 389 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin each dependency to a reviewed exact version rather than resolving the latest available release.
  2. Use a committed lockfile generated by the selected package manager.
  3. Enforce cryptographic hashes for all downloaded wheels and source distributions.
  4. Prefer reviewed binary wheels from the expected package index and reject unexpected source builds where practical.
  5. Document the trusted package index and prevent dependency resolution from untrusted or ambient indexes.
  6. Add automated dependency vulnerability and provenance scanning to the release process.
  7. Test canonicalization and signature verification against fixed conformance vectors whenever dependency versions are updated.
  8. Perform dependency upgrades as explicit reviewed releases rather than allowing versions to change during routine Skill installation.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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 (3)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

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 · SKILL.md (reported line 149)May include surrounding context.

checks array, not the retired {"expected": ...} form.

bash
curl -sS https://defaultverifier.com/settlement-witness/attest \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $SETTLEMENT_ATTEST_API_KEY" \
  -H "X-Settlement-Timestamp: $(date +%s)" \

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes a local verification skill that optionally requests DefaultVerifier-signed receipts for remote issuance, but this SECURITY.md additionally instructs use of a live remote key registry URL and discusses sending task data for remote issuance. That broadens the described operational model beyond purely bundled local verification and introduces remote interactions not reflected as code-backed local behavior in this file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.