Back to skill

Security audit

Solana Dev Skill

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Solana development guide with no hidden execution or persistence, but some code examples should be reviewed before production use.

This skill is reasonable to install for Solana development guidance. Before using its examples on mainnet or in payment flows, pin tool versions, keep dependency installation isolated from secrets, and manually review generated smart-contract code for account closing, zero-copy reads, and batch input validation.

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
programs-anchor.md:235
Finding

Unchecked Batch Length Causes an Out-of-Bounds Panic

Content
View full analysis
, amounts: Vec) -> Result<()> { let remaining = &ctx.remaining_accounts; require!(remaining.len() % 2 == 0, BatchError::InvalidSchema); for (i, chunk) in remaining.chunks(2).enumerate() { process_pair(&chunk[0], &chunk[1], amounts[i])?; } Ok(()) } ``` ### Technical Analysis The example verifies that the number of remaining accounts is even, but it does not verify that `amounts` contains one element for every account pair. Both the remaining accounts and instruction arguments are attacker-controlled. If the number of account pairs exceeds `amounts.len()`, the expression `amounts[i]` performs an out-of-bounds vector access and panics. This produces an uncontrolled program failure instead of a defined `ProgramError`. The required invariant is: ```text amounts.len() == remaining.len() / 2 ``` Although Solana transaction execution is atomic, panic-based input handling is unsafe and can consume compute before aborting. Copying this documentation pattern into production batch processors can also obscure malformed input handling and create repeatable denial-of-service behavior for transaction relayers or services that submit attacker-provided batches. ### Attack Path 1. An attacker constructs a call to the documented `batch_operation` instruction. 2. The attacker supplies an even number of remaining accounts, such as four accounts. 3. The attacker supplies fewer amount values than account pairs, such as an empty vector or one amount. 4. The modulo validation succeeds because four is even. 5. Iteration reaches an account pair for which no corresponding amount exists. 6. `amounts[i]` indexes outside the vector and panics. 7. The transaction aborts after consuming processing ...[truncated 490 chars]
Remediation
View remediation
, amounts: Vec) -> Result<()> { let remaining = &ctx.remaining_accounts; require!( remaining.len() % 2 == 0, BatchError::InvalidSchema ); require!( amounts.len() == remaining.len() / 2, BatchError::InvalidSchema ); for (chunk, amount) in remaining.chunks_exact(2).zip(amounts.iter()) { process_pair(&chunk[0], &chunk[1], *amount)?; } Ok(()) } ``` Additional hardening should include: - Define a dedicated error for mismatched amount and account counts. - Use `chunks_exact(2)` to encode the pairing requirement explicitly. - Avoid direct indexing into attacker-controlled vectors where iterator-based access is possible. - Set a maximum batch size to constrain compute consumption. - Add tests for empty input, odd account counts, too few amounts, too many amounts, and maximum permitted batch size. ]]>

T08 · Insecure Dependencies

Note
Location
testing.md:23
Finding

Unpinned Third-Party Installation Commands Create Supply-Chain Risk

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document explicitly labels an unsafe pointer cast from arbitrary account bytes to &Self as a 'Safe Pattern' while only checking length, not alignment. On Solana, account data is byte buffers with no guaranteed alignment for Rust types like Pubkey, so this can cause undefined behavior, memory safety issues, or subtly incorrect reads in on-chain code that copies the pattern.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% 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 · programs-pinocchio.md (reported line 458)May include surrounding context.

// ❌ Direct field access on packed structs creates unaligned references let b_ref = &packed.b;

// ❌ Assuming alignment without verification let config = unsafe { &*(data.as_ptr() as *const Config) };

text

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The account-closing example manually increments the destination lamports by the source balance but does not zero the source balance before realloc/close, while presenting this as a secure anti-revival pattern. In a security playbook, incomplete close logic can lead developers to implement incorrect account finalization semantics, risking inconsistent state handling or failed assumptions around closure and revival resistance.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.