Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/guides/security/canister-upgrades.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ Using the Rust CDK, the recurring timer is also lost on upgrade as explained in

- See the Rust documentation on [set_timer_interval](https://docs.rs/ic-cdk/0.6.9/ic_cdk/timer/fn.set_timer_interval.html).

<!-- Upstream: sync from dfinity/portal building-apps/security/canister-upgrades.mdx -->
<!-- Upstream: sync from dfinity/portal building-apps/security/canister-upgrades.mdx -->
16 changes: 8 additions & 8 deletions docs/guides/security/data-integrity-and-authenticity.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ sidebar:

### Security concern

ICP offers three modes of operation for canisters: `update`, `query`, and `composite_query`. For the sake of simplicity, we will club `composite_query` under queries for the rest of this section.
ICP offers three modes of operation for canisters: `update`, `query`, and `composite_query`. For simplicity, this guide treats `composite_query` methods as query methods for the rest of this section.

Update calls are slow and expensive but provide integrity guarantees as their responses include a threshold signature signed by the subnet.

On the other hand, query calls are fast since a single replica formulates the response, but **there is no integrity guarantee, since the response can be manipulated by a single replica or boundary node.** For example, if the NNS dapp fetches proposal information from the governance canister via query calls and the responding node is malicious, it can mask an ill-intentioned proposal that causes irrevocable damage as innocuous by modifying the proposal payload in the response and mislead voters into voting yes. Another consequence of query calls is that users can't rely on [canister_inspect_message](../../references/ic-interface-spec/canister-interface.md#system-api-inspect-message) as a guard. **This makes query calls, in their raw form, unfit to serve data for security-critical applications.**
On the other hand, query calls are fast since a single replica formulates the response, but **there is no integrity guarantee, since the response can be manipulated by a single replica or boundary node.** For example, if the NNS app fetches proposal information from the governance canister via query calls and the responding node is malicious, it can mask an ill-intentioned proposal that causes irrevocable damage as innocuous by modifying the proposal payload in the response and mislead voters into voting yes. Another consequence of query calls is that users can't rely on [canister_inspect_message](../../references/ic-interface-spec/canister-interface.md#system-api-inspect-message) as a guard. **This makes query calls, in their raw form, unfit to serve data for security-critical applications.**

### Using certified variables for secure queries
In certain use cases, there is a third option whereby query results can return data that has been certified by the subnet in an earlier update call. This is the concept of certified data, and it requires changes to the update call to create the certification, the query call to return the certificate, and the frontend to verify the certificate. Using certified data provides the best of both worlds with query-like response times and update-like certified responses.
In certain use cases, there is a third option whereby query results can return data that has been certified by the subnet in an earlier update call. This is the concept of certified data, and it requires changes to the update call to create the certification, the query call to return the certificate, and the frontend to verify the certificate. Using certified data provides query-like response times with update-like certified responses.

Some examples of certified variables are asset certification in [Internet Identity](https://github.com/dfinity/internet-identity/blob/b29a6f68bbe5a49d048e12bc7a3263a9f43d080b/src/internet_identity/src/main.rs#L775-L808), [NNS dapp](https://github.com/dfinity/nns-dapp/blob/372c3562127d70c2fde059bc9c268e8ae858583e/rs/src/assets.rs#L121-L145), or the [canister signature implementation in Internet Identity](https://github.com/dfinity/ic-canister-sig-creation).
Some examples of certified variables are asset certification in [Internet Identity](https://github.com/dfinity/internet-identity/blob/b29a6f68bbe5a49d048e12bc7a3263a9f43d080b/src/internet_identity/src/main.rs#L775-L808), [NNS app](https://github.com/dfinity/nns-dapp/blob/372c3562127d70c2fde059bc9c268e8ae858583e/rs/src/assets.rs#L121-L145), or the [canister signature implementation in Internet Identity](https://github.com/dfinity/ic-canister-sig-creation).

:::tip
Certified variables are an advanced feature that require careful implementation of authenticated data structures and verification on the canister and client sides, respectively. **If the client doesn't require fast response times, call the query method as an update call (replicated query).** The response would be certified by the subnet, and a single malicious or boundary node can't modify the response.
Expand Down Expand Up @@ -610,20 +610,20 @@ function bigEndian(n) {
}
```

## Use HTTP asset certification and avoid serving your dapp through `raw.icp0.io`
## Use HTTP asset certification and avoid serving your app through `raw.icp0.io`

### Security concern

Dapps on ICP can use [asset certification](https://learn.internetcomputer.org/hc/en-us/articles/34276431179412-Asset-Certification) to make sure the HTTP assets delivered to the browser are authentic (i.e., threshold-signed by the subnet). If an app does not do asset certification, it can only be served insecurely through `raw.icp0.io`, where no asset certification is checked. This is insecure since a single malicious node or boundary node can freely modify the assets delivered to the browser.
Apps on ICP can use [asset certification](https://learn.internetcomputer.org/hc/en-us/articles/34276431179412-Asset-Certification) to make sure the HTTP assets delivered to the browser are authentic (i.e., threshold-signed by the subnet). If an app does not do asset certification, it can only be served insecurely through `raw.icp0.io`, where no asset certification is checked. This is insecure since a single malicious node or boundary node can freely modify the assets delivered to the browser.

If an app is served through `raw.icp0.io` in addition to `icp0.io`, an adversary may trick users (phishing) into using the insecure `raw.icp0.io`.

### Recommendation

- Only serve assets through `<canister-id>.icp0.io`, where the boundary nodes enforce response verification on the served assets. Do not serve through `<canister-id>.raw.icp0.io`.

- Serve assets using the asset canister, which creates asset certification automatically, or add the `ic-certificate` header including the asset certification as, e.g., done in the [NNS dapp](https://github.com/dfinity/nns-dapp) and [Internet Identity](https://github.com/dfinity/internet-identity).
- Serve assets using the asset canister, which creates asset certification automatically, or add the `ic-certificate` header including the asset certification as, e.g., done in the [NNS app](https://github.com/dfinity/nns-dapp) and [Internet Identity](https://github.com/dfinity/internet-identity).

- Check in the canister's `http_request` method if the request came through raw. If so, return an error and do not serve any assets.

<!-- Upstream: sync from dfinity/portal building-apps/security/data-integrity-and-authenticity.mdx -->
<!-- Upstream: sync from dfinity/portal building-apps/security/data-integrity-and-authenticity.mdx -->
6 changes: 3 additions & 3 deletions docs/guides/security/data-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ By default, canisters provide integrity but not confidentiality. Data stored on

- Consider end-to-end encrypting any private or personal data (e.g., a user's personal or private information) on canisters.

- The example dapp [encrypted notes](https://github.com/dfinity/examples/tree/master/motoko/encrypted-notes-dapp) illustrates how end-to-end encryption can be done.
- The [encrypted notes](https://github.com/dfinity/examples/tree/master/motoko/encrypted-notes-dapp) example app illustrates how end-to-end encryption can be done.

## Create backups

### Security concern

A canister could be rendered unusable and impossible to upgrade. For example, due to one of the following reasons:

- It has a faulty upgrade process due to some bug from the dapp developer.
- It has a faulty upgrade process due to some bug from the app developer.

- The state becomes inconsistent or corrupt because of a bug in the code that persists data.

Expand All @@ -91,4 +91,4 @@ A canister could be rendered unusable and impossible to upgrade. For example, du

- See the "Backup and recovery" section in [how to audit an Internet Computer canister](https://www.joachim-breitner.de/blog/788-How_to_audit_an_Internet_Computer_canister).

<!-- Upstream: sync from dfinity/portal building-apps/security/data-storage.mdx -->
<!-- Upstream: sync from dfinity/portal building-apps/security/data-storage.mdx -->
Loading
Loading