Back to skill

Security audit

soft-ip-full-lifecycle-zijian

Security checks for vulnerabilities and agentic risk

Overview

The skill is broadly coherent for a paid Chinese software-copyright self-assessment, but it needs Review because it stores user questions locally, uses weak local payment authorization, and documents a runtime npx payment command.

Review before installing. Avoid putting source code, applicant details, trade secrets, or sensitive ownership facts in the initial question unless you accept local cleartext storage under your home directory. Use the npx sandbox payment command only in a contained environment, and do not rely on this package's local payment verification as strong proof of payment.

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
scripts/service.py:55
Finding

Local Order File Allows Forged Payment Authorization

Content
View full analysis

Vulnerability Details

File Location: scripts/service.py, lines 55–88
Vulnerability Type: Insufficient payment credential validation
Risk Level: High

Vulnerable Code:

python
def is_credential_valid(order_data: dict) -> bool:
    credential = order_data.get("payCredential")
    if not credential:
        return False
    credential_ts = order_data.get("credentialTimestamp")
    if credential_ts and time.time() - credential_ts > CREDENTIAL_TTL:
        return False
    return True


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Verify payment and authorize soft-ip-zijian compliance review"
    )
    parser.add_argument("order_no", help="Order number from Phase 1")
    args = parser.parse_args()

    indicator = compute_indicator(SLUG)

    try:
        order_data = _load_order(indicator, args.order_no)
    except Exception as e:
        print("PAY_STATUS: ERROR")
        print(f"ERROR_INFO: Order file read failed: {e}")
        sys.exit(1)

    if not is_credential_valid(order_data):
        print("PAY_STATUS: ERROR")
        print("ERROR_INFO: No valid payment credential found. Please complete payment via clawtip first.")
        sys.exit(1)

    pay_status = order_data.get("payStatus", "SUCCESS")
    print(f"PAY_STATUS: {pay_status}")

    if pay_status != "SUCCESS":
        print(f"ERROR_INFO: Payment status is '{pay_status}', cannot proceed")
        sys.exit(1)

Technical Analysis

Payment authorization is based entirely on fields read from a locally writable JSON order file. The application considers any non-empty payCredential value valid without cryptographically verifying its origin or contents.

The implementation does not verify:

  • A digital signature or message authentication code from the payment provider.
  • That the credential is bound to the supplied order number.
  • The expected payment amoun ...[truncated 1480 chars]
Remediation
View remediation

Remediation Suggestions

  • Require a cryptographically signed payment credential from the trusted payment provider.
  • Verify the signature using a pinned, trusted public key or validate a provider-generated MAC using a securely managed secret.
  • Bind the credential to the exact order number, amount, currency, recipient, skill identifier, issuance time, and expiration time.
  • Require a valid timestamp and reject credentials with missing, malformed, expired, or unreasonably future-dated timestamps.
  • Require an explicit SUCCESS status from authenticated credential content; never default a missing status to success.
  • Do not trust mutable order-file fields as proof of payment.
  • Where supported, query the trusted payment provider for order status over an authenticated channel.
  • Mark credentials as consumed or otherwise enforce replay protection if each payment should authorize only one delivery.
  • Use constant-time cryptographic verification and fail closed on every parsing or validation error.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/create_order.py:159
Finding

Encryption Failure Causes Plaintext Payment Metadata Storage

Content
View full analysis

Vulnerability Details

File Location: scripts/create_order.py, lines 159–172
Vulnerability Type: Fail-open encryption and unauthenticated ECB encryption
Risk Level: Medium

Vulnerable Code:

python
encrypted_data = encrypt_payload
if sm4_key:
    try:
        if len(sm4_key) == 32 and all(c in "0123456789abcdefABCDEF" for c in sm4_key):
            encrypted_data = _sm4_encrypt_hex(sm4_key, encrypt_payload)
        else:
            import base64
            key_hex = base64.b64decode(sm4_key).hex()
            encrypted_data = _sm4_encrypt_hex(key_hex, encrypt_payload)
    except Exception as e:
        print(f"WARNING: SM4 encryption failed: {e}")

Technical Analysis

encrypted_data is initialized with the plaintext JSON payment payload. When the encryption key is absent, malformed, incorrectly encoded, or has an invalid length, the function merely emits a warning and continues using the plaintext value.

Consequently, the order file can expose the order number, amount, and payment recipient in a field whose name and documentation imply that it contains ciphertext. Callers are not given a reliable machine-readable indication that encryption failed.

The custom implementation also uses SM4 in ECB mode. ECB is deterministic, exposes repeated plaintext-block patterns, and does not provide integrity or authenticity. An attacker able to modify the order file may alter or replace ciphertext without an authenticated-encryption tag detecting the modification.

Attack Path

  1. Configure CLAWTIP_SM4_KEY with an invalid hexadecimal or Base64 value, an incorrectly sized key, or leave it unset.
  2. Run scripts/create_order.py.
  3. Encryption either is skipped or raises an exception.
  4. The exception is reduced to a warning, and order creation continues.
  5. The unencrypted JSON payment payload is written into the encrypted_data field of the local order file.
  6. Any process or us ...[truncated 641 chars]
Remediation
View remediation

Remediation Suggestions

  • Abort order creation when the encryption key is absent, malformed, or unusable if encryption is required by the workflow.
  • Never initialize an encryption-designated field with plaintext as a fallback.
  • Return a nonzero exit status on encryption failure and avoid writing a partially protected order.
  • Replace SM4-ECB with an authenticated-encryption construction approved by the target environment, using a fresh cryptographically secure nonce for every order.
  • Store a versioned envelope containing the algorithm identifier, nonce, ciphertext, and authentication tag.
  • Strictly validate the key's encoding and decoded length before processing the payload.
  • Restrict order-file and directory permissions to the owning user, such as mode 0600 for files and 0700 for directories where supported.
  • Ensure logs do not expose the key or plaintext payload when reporting encryption errors.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:96
Finding

Documented Workflow Downloads and Executes an External npm Package at Runtime

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 96–100
Vulnerability Type: Unverified runtime dependency retrieval and execution
Risk Level: Medium

Vulnerable Code:

bash
npx --yes @clawtip/clawtip-sandbox-cli@1.0.0 pay -o <ORDER_NO> -i <INDICATOR> -v 1.0.12

Technical Analysis

The documented sandbox payment workflow invokes npx --yes, which may retrieve an npm package and execute its code immediately. Pinning the direct package to version 1.0.0 reduces accidental version drift but does not verify the artifact's integrity or independently lock and validate its complete transitive dependency graph.

The project does not include a vendored and audited copy of the client, a lockfile with integrity metadata, or an independently verified artifact checksum. Execution is also unattended because of --yes.

This creates a supply-chain execution boundary outside the reviewed project. If the named package, one of its transitive dependencies, the package registry, or the package-resolution path is compromised, attacker-controlled code could execute under the account invoking the documented command.

Attack Path

  1. An attacker compromises the published package artifact, one of its transitive dependencies, or the registry path used to resolve it.
  2. A user follows the documented sandbox workflow.
  3. npx --yes downloads the package and its dependencies without an interactive confirmation step.
  4. npm lifecycle hooks, the package entry point, or a compromised dependency executes attacker-controlled code.
  5. The code runs with the filesystem, environment-variable, network, and process privileges of the invoking user.

Impact Assessment

Successful supply-chain compromise could result in arbitrary code execution with the privileges of the user running the payment command. Depending on that user's environment, the external package could access local order files, environment va ...[truncated 293 chars]

Remediation
View remediation

Remediation Suggestions

  • Avoid downloading and executing dependencies dynamically during the payment workflow.
  • Vendor and audit the required client or distribute it as a separately verified artifact from a trusted source.
  • Maintain a lockfile that fixes the complete dependency graph and includes registry integrity hashes.
  • Verify artifact checksums or signatures against values delivered through an independent trusted channel.
  • Use a trusted internal registry or allowlisted package mirror where appropriate.
  • Disable unnecessary npm lifecycle scripts during installation when compatible with the package.
  • Run the payment client in a sandbox with minimal filesystem, environment-variable, process, and network access.
  • Avoid unattended --yes execution when user confirmation and artifact review are practical.
  • Periodically review the direct package and all transitive dependencies for ownership changes, known vulnerabilities, and unexpected install scripts.
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill markets itself primarily as a software copyright compliance review service, but the documented executable workflow only creates local payment orders, invokes payment, and verifies payment before telling the AI to provide an assessment in chat. This mismatch can mislead users about what the code actually does, obscure the real data handling behavior, and make it harder for reviewers to assess whether sensitive materials are processed, stored, or transmitted as claimed.

Content

No source excerpt is available for this finding.

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.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script's docstring and runtime notice tell users that only limited payment metadata is stored, but the code also persists the full user question along with description and resource URL. In this skill's context, the question may contain sensitive copyright, source code, applicant, or compliance details, so inaccurate disclosure creates a privacy and informed-consent failure that can expose users to unintended local data retention.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The order file stores the user's full question in cleartext JSON under the user's home directory, while the user-facing notice incorrectly implies that only order metadata is saved. Because this skill concerns software copyright filings, users may include source code descriptions, ownership facts, or other sensitive business information in the question, making local persistence a meaningful confidentiality risk on shared or compromised systems.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The script creates persistent session-like state by writing order data, including the user's question, to a predictable location in the home directory. In this skill's context, such persistence is more sensitive because user prompts may contain proprietary software and rights-attribution information, so leftover local artifacts can be accessed later by other users, processes, backups, or forensic collection.

Content

Scanner excerpt · scripts/create_order.py (reported line 181)May include surrounding context.

python
if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Create order for soft-ip-zijian compliance review service"
    )
    parser.add_argument("question", help="User question / consultation content")
    args = parser.parse_args()

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
74% confidence
Finding

The natural-language strings hard-code a China-specific payment and service context, including "1.9 yuan" and the zijian self-assessment/compliance review branding, without indicating any user opt-in or locale choice. Under the policy, locale-specific constraints should either be explicitly justified as region-specific or offer the user a choice.

Content

No source excerpt is available for this finding.