Back to skill

Security audit

Bridge Stablecoin

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent Circle USDC bridging guide, but users should treat its examples carefully because they involve signing credentials and transaction code.

Install only if you intend to build Circle Bridge Kit/CCTP USDC transfers. Use testnets and low-balance test wallets first, keep private keys and Circle secrets out of logs and source control, pin reviewed dependency versions, and add an explicit confirmation step before any mainnet bridge transaction.

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
references/adapter-private-key.md:20
Finding
Bridge examples execute fund transfers without mandatory confirmation or input validation<![CDATA[ ## Vulnerability Details **File Location**: `references/adapter-private-key.md:20-24,32` **Additional Locations**: `references/adapter-private-key.md:55-59,67`; `references/adapter-circle-wallets.md:36-48,56`; `references/adapter-wagmi.md:57-61` **Vulnerability Type**: Missing transaction confirmation and input validation **Risk Level**: Medium ### Vulnerable Code ```ts const result = await kit.bridge({ from: { adapter, chain: "Arc_Testnet" }, to: { adapter, chain: "Base_Sepolia" }, amount: "1.00", }); void bridgeUSDC(); ``` The same automatic execution pattern appears in the EVM-to-Solana and Circle Wallets examples: ```ts const result = await kit.bridge({ from: { adapter: evmAdapter, chain: "Ethereum_Sepolia" }, to: { adapter: solanaAdapter, chain: "Solana_Devnet" }, amount: "1.00", }); void bridgeUSDC(); ``` ```ts const result = await kit.bridge({ from: { adapter, chain: "Arc_Testnet", address: process.env.EVM_WALLET_ADDRESS!, }, to: { adapter, chain: "Solana_Devnet", address: process.env.SOLANA_WALLET_ADDRESS!, }, amount: "1.00", }); void bridgeUSDC(); ``` ### Technical Analysis The reference implementations call `kit.bridge()` without validating the source chain, destination chain, recipient address, amount, token, wallet balance, or selected network. The standalone examples then invoke `bridgeUSDC()` immediately, meaning that running the example can submit an approval, burn, attestation, and mint workflow without a separate confirmation boundary. This implementation contradicts the security rules in `SKILL.md:245-248`, which require explicit confirmation of the source chain, destination chain, recipient, amount, and token before bridging, as well as validation of all transaction inputs. The current examples use test networks and a fixed amount, which limits their immediate financial impact. However, they are presented as implementation patterns and can become unsafe when users replace ...[truncated 1262 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic invocation such as `void bridgeUSDC()` from reference implementations. 2. Expose the bridge operation as a function that must be called only after an explicit confirmation step. 3. Before calling `kit.bridge()`, validate: - Source and destination chains against an allowlist. - That source and destination are not accidentally identical. - Recipient address syntax and network compatibility. - Amount as a positive, bounded decimal value. - Token identity and contract address. - Wallet balance and expected network fees. - Whether the selected environment is testnet or mainnet. 4. Display a final immutable transaction summary containing the token, amount, source chain, destination chain, recipient, forwarding-service use, and estimated fees. 5. Require explicit user confirmation immediately before submission, especially for mainnet operations. 6. Reject mainnet transfers unless mainnet use was explicitly selected and confirmed. 7. Add a configurable transfer limit and require stronger confirmation for high-value transactions. 8. Keep transaction construction separate from transaction submission so parameters can be reviewed and tested without moving funds. ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:15
Finding
Security-sensitive SDK dependencies are installed without version pinning<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:15-27` **Additional Locations**: `references/adapter-circle-wallets.md:8`; `references/adapter-wagmi.md:10` **Vulnerability Type**: Unpinned security-sensitive dependencies **Risk Level**: Low ### Vulnerable Code ```bash npm install @circle-fin/bridge-kit @circle-fin/adapter-viem-v2 ``` ```bash npm install @circle-fin/adapter-solana-kit ``` ```bash npm install @circle-fin/adapter-circle-wallets ``` ### Technical Analysis The installation instructions do not specify reviewed package versions. Consequently, package resolution can select whichever compatible release is current at installation time rather than a release that was reviewed with the Skill. These dependencies are security-sensitive because the adapters receive private keys, Circle API credentials, entity secrets, wallet providers, or transaction-signing authority. A compromised, malicious, or unexpectedly incompatible future package release could therefore have substantially greater impact than a typical application dependency. The package names are consistent with the declared Circle integration, and the audit found no evidence of typosquatting, a nonstandard package registry, or an existing malicious dependency. The issue is the absence of reproducible dependency resolution and supply-chain controls. ### Attack Path 1. A developer follows the documented unpinned `npm install` commands. 2. npm resolves the package versions available at that time. 3. An upstream account compromise, malicious release, or unsafe future version introduces harmful behavior. 4. The newly resolved package runs in an application that supplies wallet credentials or signing authority. 5. The compromised dependency can inspect secrets available to its process, alter transaction parameters, or request unauthorized signatures. 6. Resulting activity can include credential disclosure or unauthorized blockchain transactions, subject to the dependency's runti ...[truncated 488 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin each dependency to an exact reviewed version rather than allowing installation of the latest release. 2. Provide and commit a lockfile containing resolved versions and integrity hashes. 3. Use `npm ci` in automated and production environments to enforce reproducible installation. 4. Review package provenance, maintainer identity, release history, and registry source before upgrades. 5. Enable dependency scanning and alerting for known vulnerabilities and unexpected package changes. 6. Test dependency upgrades in an isolated environment before exposing them to real credentials or funded wallets. 7. Run bridge integrations with narrowly scoped credentials and low-balance wallets where operationally possible. 8. Document a controlled update procedure that requires code review and security testing before changing pinned versions. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (6)

Vague Triggers

Medium
Confidence
93% confidence
Finding
The description includes generic triggers such as "crosschain transfer" and "move USDC between chains" without clear activation boundaries or exclusion conditions. In a manifest-style file, these phrases are broad enough to overlap with general discussion of blockchain transfers, which can make invocation scope ambiguous.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- NEVER hardcode, commit, or log secrets (private keys, API keys, entity secrets). ALWAYS use environment variables or a secrets manager. Add `.gitignore` entries for `.env*` and secret files when scaffolding.
- NEVER pass private keys as plain-text CLI flags. Prefer encrypted keystores or interactive import.
- ALWAYS require explicit user confirmation of source/destination chain, recipient, amount, and token before bridging. NEVER auto-execute fund movements on mainnet.
- ALWAYS warn when targeting mainnet or exceeding safety thresholds (e.g., >100 USDC).
- ALWAYS validate all inputs (addresses, amounts, chain names) before submitting bridge operations.
- ALWAYS warn before interacting with unaudited or unknown contracts.
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.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The example performs an actual bridge operation that can move real USDC, but the surrounding documentation does not clearly warn that it initiates a live asset transfer or advise readers to confirm network, wallet, amount, and environment before running it. In a bridge-related skill, this is especially risky because users may copy-paste the sample and unintentionally trigger irreversible cross-chain movement of funds, particularly if production credentials are present in environment variables.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This markdown file contains code that reads a private key from an environment variable to create a signing adapter, but the surrounding documentation does not warn users that the example requires highly sensitive credentials. Under the markdown criteria for SQP-2, skill descriptions should disclose behaviors affecting privacy or system integrity, and use of raw private keys is safety-critical.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The example initiates a bridge transaction that can move USDC between chains, which can affect user funds and may be irreversible if misconfigured. The markdown description presents this as a reference implementation but does not include any warning about transaction costs, testnet/mainnet context, or the consequences of executing a transfer.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This example reads both EVM and Solana private keys from environment variables, but the markdown provides no explicit warning about safeguarding those secrets. Because compromise of either key could enable unauthorized transactions, the documentation should clearly disclose the sensitivity of these inputs.

Static analysis

No suspicious patterns detected.