canister-security

Implements security patterns for Internet Computer canisters in Motoko and Rust.

Updated Apr 3, 2026
One-click install
npx skills add https://github.com/phukrit7171/Relationship-Smart-Contract-ICP --skill canister-security-phukrit7171
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: canister-security
Source: https://github.com/phukrit7171/Relationship-Smart-Contract-ICP/tree/main/.agents/skills/canister-security
Command: npx skills add https://github.com/phukrit7171/Relationship-Smart-Contract-ICP --skill canister-security-phukrit7171

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Internet Computer canisters face unique security risks from the async messaging model: TOCTOU vulnerabilities between await calls, reentrancy attacks, anonymous principal abuse, cycle drain, and permanent upgrade failures. This Skill provides copy-paste correct patterns that prevent these exploits when writing or modifying canisters. ## Core Features & Use Cases - Access Control Patterns: Guard functions and CDK guard attributes that reject anonymous principals and enforce owner/admin roles in both Motoko and Rust. - Reentrancy Prevention: CallerGuard pattern using per-caller locking with Drop/finally cleanup that survives callback traps. - Async Safety & Upgrade Protection: Saga pattern guidance, bounded wait calls, stable memory strategies, and pre_upgrade trap avoidance. - Use Case: When building a Rust canister that handles token transfers via inter-canister calls, apply the CallerGuard pattern to block concurrent requests from the same principal and use bounded_wait calls so a malicious callee cannot block upgrades. ## Quick Start Review my canister code for security vulnerabilities and add access control guards plus reentrancy protection to the update methods.

Frequently Asked Questions about canister-security

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I prevent reentrancy attacks on Internet Computer canisters?

Use the CallerGuard pattern: acquire a per-caller lock before making inter-canister calls and release it in a finally block (Motoko) or via the Drop trait (Rust). This rejects concurrent calls from the same principal while the first call awaits a response.

How to implement access control in a Rust IC canister?

Use the ic-cdk guard attribute (#[update(guard = "require_admin")]) with functions returning Result<(), String>. Guards run before method code executes, so you cannot forget the check. Always reject the anonymous principal and verify caller against owner or admin lists.

Is canister_inspect_message a reliable security boundary?

No. inspect_message runs on a single replica without full consensus, can be skipped by a malicious replica, and is never called for inter-canister or query calls. Use it only as a cycle-saving optimization and duplicate all access checks inside every update method.

Why does a canister become non-upgradeable after pre_upgrade traps?

If pre_upgrade traps, for example when serializing too much heap data exceeds the instruction limit, the upgrade fails permanently. Avoid this by using ic-stable-structures in Rust or persistent actor declarations in Motoko, which store data directly in stable memory.

What happens when a canister runs out of cycles?

When cycles drop below the freezing threshold reserve (default ~30 days), the canister rejects all update calls; at zero cycles it is uninstalled. Monitor balances actively, increase the freezing threshold for high-value canisters, and set up automated top-ups.

Can I store secrets or private keys in canister state?

No. Canister memory on standard application subnets is readable by node operators, so private keys, API secrets, and passwords must never be stored there. For on-chain secret management, use vetKD (threshold key derivation) instead.