Security Overview
This section provides security best practices for developing canisters and web apps served by canisters on ICP. These best practices are mostly inspired by issues found in security reviews.
The goal of these best practices is to enable developers to identify and address potential issues early during the development of new dapps, and not only in the end when (if at all) a security review is done. Ideally, this will make the development of secure dapps more efficient.
Some excellent canister best practices linked here are from effective Rust canisters and how to audit an ICP canister. The relevant sections are linked in the individual best practices.
Target audience
Section titled “Target audience”The target audience for these documents is any developer working on ICP canisters or web apps and anyone who reviews such code.
Disclaimers and limitations
Section titled “Disclaimers and limitations”The collection of best practices may grow over time. While it is useful to improve the security of dapps on ICP, such a list will never be complete and will never cover all potential security concerns. For example, there will always be attack vectors very specific to a dapp’s use cases that cannot be covered by general best practices. Thus, following the best practices can complement, but not replace, security reviews. Especially for security-critical dapps, it is recommended to perform security reviews or audits. Furthermore, please note that the best practices are currently not ordered according to risk or priority.
Further reading
Section titled “Further reading”Below are resources covering security best practices for technologies commonly used in ICP dapps. These are equally important as the ICP-specific guidelines and should be studied carefully.
General
Section titled “General”- How to audit an Internet Computer canister by Joachim Breitner
- OWASP application security verification standard
- OWASP top ten
- Secure Rust guidelines, in particular unsafe code, overflows and Cargo-audit
- For overflowing operations, consider using
saturatedorcheckedvariants, such assaturated_add,saturated_sub,checked_add,checked_sub. See the Rust docs foru32.
- For overflowing operations, consider using
Crypto
Section titled “Crypto”- OWASP cryptographic failures points out issues related to cryptography, or the lack thereof.
- OWASP application security verification standard (see Section V6)
- Use the Web Crypto API. Storing key material in the browser storage (such as sessionStorage or localStorage) is considered unsafe because these keys can be accessed by JavaScript code, e.g. in an XSS attack. To protect the private key from direct access, use Web Crypto’s generateKey with
extractable=false.
Web security
Section titled “Web security”- Resources for setting security headers:
- SSL server test
- Don’t use features that could lead to an XSS vulnerability, such as @html in Svelte.
- Log out securely. Clear all session data (especially sessionStorage and localStorage), clear IndexedDB, etc. on logout. Make sure other browser tabs showing the same origin are logged out if the logout is triggered in one tab. This may not happen automatically when the ICP JavaScript agent is used, since the ICP JavaScript agent keeps the private key in memory once initialized.
Testing
Section titled “Testing”- In effective Rust canisters: test upgrades, make code target-independent
- Consider PocketIC for canister testing