Back to all guides
Topic:Developers
Developer Security

How to Audit an ICP Canister: Security Best Practices & Vulnerability Prevention

Auditing canisters on the Internet Computer requires a fundamentally different mindset than evaluating Solidity EVM smart contracts. Canisters operate asynchronously, persist state across stable memory, and pay for their own cycles. Here is the definitive security audit guide.

ICPay
By ICPay TeamOfficial

September 10, 2026

9 min read

Security Tooling with icFalcon

Explore icFalcon Developer Security Tools to inspect controller hierarchies, monitor cycle depletion rates, and automate canister health checks.

1. The 5 Most Common Canister Vulnerabilities

1. Inter-Canister Reentrancy Across Awaits

Whenever an asynchronous inter-canister call is awaited, execution yields. If a user calls a withdraw method twice in parallel before the first call finishes, both could pass balance checks. Always apply the Checks-Effects-Interactions pattern or reentrancy locks before the `await`.

2. Unbounded State & Cycle Exhaustion (DoS)

Publicly accessible update functions that append user data to unbounded data structures without charging fees or rate-limiting allow malicious actors to flood the canister until its cycle balance drops to zero and it freezes.

3. Traps in Inter-Canister Callbacks

If an inter-canister call receives a trap (panic) in a callback, any state changes made prior to the call within that method may be reverted, leaving the canister in an inconsistent state.

4. Insecure Controller Management

Leaving private single-principal controllers on production canisters rather than transferring control to an immutable black-hole canister or a decentralized NNS/SNS DAO.

5. Stable Memory Serialization Failures

Upgrading a canister with incompatible Candid types can cause deserialization failure during `post_upgrade`, permanently bricking the canister state.

2. The Canister Security Audit Checklist

Check AreaRequirementTool / Action
AuthenticationAssert caller != Principal.anonymous() on all non-public endpoints.Caller guard assertion
ReentrancyState is mutated before any `await` call.Manual code audit
Cycle ReservesCanister monitors cycle burn rates and alerts before freezing.ICPay Canister Tools
UpgradesSnapshots taken before upgrades; stable memory tested.Snapshot Tool

Related Reading