Skip to content

Commit

Permalink
fix: add icp0-api.io to default CSP; default to allow raw access
Browse files Browse the repository at this point in the history
  • Loading branch information
ericswanson-dfinity committed Sep 15, 2023
1 parent 9e74a14 commit 6be85a4
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 30 deletions.
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ The `use-old-metering` flag enables old metering in replica. The new metering is

The flag is temporary and will be removed in a few months.

### fix: added https://icp-api.io to the default Content-Security-Policy header

Existing projects will need to change this value in .ic-assets.json or .ic-assets.json5 to include https://icp-api.io

All projects will need to redeploy.

### fix: access to raw assets is now enabled by default

The default value for `allow_raw_access` is now `true`. This means that by default, the frontend canister will no longer restrict the access of traffic to the `<canister-id>.raw.icp0.io` domain, and will no longer automatically redirect all requests to the certified domain (`<canister-id>.icp0.io`), unless configured explicitly.

Note that existing projects that specify `"allow_raw_access": false` in .ic-assets.json5 will need to change or remove this value manually in order to allow raw access.

### feat!: Removed dfx nns and dfx sns commands

Both have now been turned into the dfx extensions. In order to obtain them, please run `dfx extension install nns` and `dfx extension install sns` respectively. After the installation, you can use them as you did before: `dfx nns ...`, and `dfx sns ...`.
Expand Down Expand Up @@ -166,7 +178,9 @@ Updated Motoko to [0.9.7](https://github.com/dfinity/motoko/releases/tag/0.9.7)

### Frontend canister

- Module hash: 88d1e5795d29debc1ff56fa0696dcb3adfa67f82fe2739d1aa644263838174b9
- Module hash: e20be8df2c392937a6ae0f70d20ff23b75e8c71d9085a8b8bb438b8c2d4eafe5
- https://github.com/dfinity/sdk/pull/3337
- https://github.com/dfinity/sdk/pull/3298
- https://github.com/dfinity/sdk/pull/3256
- https://github.com/dfinity/sdk/pull/3252
- https://github.com/dfinity/sdk/pull/3249
Expand Down
34 changes: 17 additions & 17 deletions e2e/tests-dfx/assetscanister.bash
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ check_permission_failure() {
dfx identity get-principal --identity prepare
dfx canister call e2e_project_frontend list_permitted '(record { permission = variant { Commit }; })'
assert_command dfx deploy e2e_project_frontend --by-proposal --identity prepare
assert_contains "Proposed commit of batch 2 with evidence 4301263f1fcc0d19ef92cfb6774c4da92bf1a9d2002a293a9d95d97819c02958. Either commit it by proposal, or delete it."
assert_contains "Proposed commit of batch 2 with evidence 164fcc4d933ff9992ab6ab909a4bf350010fa0f4a3e1e247bfc679d3f45254e1. Either commit it by proposal, or delete it."

assert_command_fail dfx deploy e2e_project_frontend --by-proposal --identity prepare
assert_contains "Batch 2 is already proposed. Delete or execute it to propose another."

assert_command dfx deploy e2e_project_frontend --compute-evidence --identity anonymous
# shellcheck disable=SC2154
assert_eq "4301263f1fcc0d19ef92cfb6774c4da92bf1a9d2002a293a9d95d97819c02958" "$stdout"
assert_eq "164fcc4d933ff9992ab6ab909a4bf350010fa0f4a3e1e247bfc679d3f45254e1" "$stdout"

ID=$(dfx canister id e2e_project_frontend)
PORT=$(get_webserver_port)
Expand All @@ -161,9 +161,9 @@ check_permission_failure() {
assert_command_fail dfx canister call e2e_project_frontend commit_proposed_batch "$wrong_commit_args" --identity commit
assert_match "batch computed evidence .* does not match presented evidence"

commit_args='(record { batch_id = 2; evidence = blob "\43\01\26\3f\1f\cc\0d\19\ef\92\cf\b6\77\4c\4d\a9\2b\f1\a9\d2\00\2a\29\3a\9d\95\d9\78\19\c0\29\58" } )'
commit_args='(record { batch_id = 2; evidence = blob "\16\4f\cc\4d\93\3f\f9\99\2a\b6\ab\90\9a\4b\f3\50\01\0f\a0\f4\a3\e1\e2\47\bf\c6\79\d3\f4\52\54\e1" } )'
assert_command dfx canister call e2e_project_frontend validate_commit_proposed_batch "$commit_args" --identity commit
assert_contains "commit proposed batch 2 with evidence 4301"
assert_contains "commit proposed batch 2 with evidence 164f"
assert_command dfx canister call e2e_project_frontend commit_proposed_batch "$commit_args" --identity commit
assert_eq "()"

Expand Down Expand Up @@ -213,21 +213,21 @@ check_permission_failure() {
dfx identity get-principal --identity prepare
dfx canister call e2e_project_frontend list_permitted '(record { permission = variant { Commit }; })'
assert_command dfx deploy e2e_project_frontend --by-proposal --identity prepare
assert_contains "Proposed commit of batch 2 with evidence 1b45c8b1d0deec88ac032590e0f1cd9ab407f796e827aac880f4ffb035fdc200. Either commit it by proposal, or delete it."
assert_contains "Proposed commit of batch 2 with evidence 9b72eee7f0d7af2a9b41233c341b1caa0c905ef91405f5f513ffb58f68afee5b. Either commit it by proposal, or delete it."

assert_command dfx deploy e2e_project_frontend --compute-evidence --identity anonymous
# shellcheck disable=SC2154
assert_eq "1b45c8b1d0deec88ac032590e0f1cd9ab407f796e827aac880f4ffb035fdc200" "$stdout"
assert_eq "9b72eee7f0d7af2a9b41233c341b1caa0c905ef91405f5f513ffb58f68afee5b" "$stdout"

ID=$(dfx canister id e2e_project_frontend)
PORT=$(get_webserver_port)

assert_command_fail curl --fail -vv http://localhost:"$PORT"/sample-asset.txt?canisterId="$ID"
assert_contains "The requested URL returned error: 404"

commit_args='(record { batch_id = 2; evidence = blob "\1b\45\c8\b1\d0\de\ec\88\ac\03\25\90\e0\f1\cd\9a\b4\07\f7\96\e8\27\aa\c8\80\f4\ff\b0\35\fd\c2\00" } )'
commit_args='(record { batch_id = 2; evidence = blob "\9b\72\ee\e7\f0\d7\af\2a\9b\41\23\3c\34\1b\1c\aa\0c\90\5e\f9\14\05\f5\f5\13\ff\b5\8f\68\af\ee\5b" } )'
assert_command dfx canister call e2e_project_frontend validate_commit_proposed_batch "$commit_args" --identity commit
assert_contains "commit proposed batch 2 with evidence 1b45c8b1d0deec88ac032590e0f1cd9ab407f796e827aac880f4ffb035fdc200"
assert_contains "commit proposed batch 2 with evidence 9b72eee7f0d7af2a9b41233c341b1caa0c905ef91405f5f513ffb58f68afee5b"
assert_command dfx canister call e2e_project_frontend commit_proposed_batch "$commit_args" --identity commit
assert_eq "()"

Expand Down Expand Up @@ -1398,28 +1398,28 @@ CHERRIES" "$stdout"
"cache": {
"max_age": 2000
},
"allow_raw_access": false
"allow_raw_access": true
}'
assert_match 'WARN: 4 unmatched configurations in .*/src/e2e_project_frontend/assets/somedir/.ic-assets.json config file:'
assert_contains 'WARN: {
"match": "nevermatchme",
"headers": {},
"ignore": false,
"allow_raw_access": false
"allow_raw_access": true
}
WARN: {
"match": "nevermatchmetoo",
"headers": {},
"ignore": false,
"allow_raw_access": false
"allow_raw_access": true
}
WARN: {
"match": "non-matcher",
"headers": {
"x-header": "x-value"
},
"ignore": false,
"allow_raw_access": false
"allow_raw_access": true
}'
# splitting this up into two checks, because the order is different on macos vs ubuntu
assert_contains 'WARN: {
Expand All @@ -1428,7 +1428,7 @@ WARN: {
"x-header": "x-value"
},
"ignore": false,
"allow_raw_access": false
"allow_raw_access": true
}'
}

Expand Down Expand Up @@ -1456,7 +1456,7 @@ WARN: {
record {
headers = opt vec { record { "x-key"; "x-value" } };
is_aliased = opt true;
allow_raw_access = opt false;
allow_raw_access = opt true;
max_age = opt (2_000 : nat64);
},
)'
Expand All @@ -1476,7 +1476,7 @@ WARN: {
record {
headers = opt vec { record { "x-key"; "x-value" } };
is_aliased = opt true;
allow_raw_access = opt false;
allow_raw_access = opt true;
max_age = opt (5 : nat64);
},
)'
Expand All @@ -1489,7 +1489,7 @@ WARN: {
record {
headers = opt vec { record { "new-key"; "new-value" } };
is_aliased = opt true;
allow_raw_access = opt false;
allow_raw_access = opt true;
max_age = opt (5 : nat64);
},
)'
Expand Down Expand Up @@ -1585,7 +1585,7 @@ WARN: {
record {
headers = null;
is_aliased = null;
allow_raw_access = opt false;
allow_raw_access = opt true;
max_age = null;
},
)'
Expand Down
6 changes: 3 additions & 3 deletions src/canisters/frontend/ic-asset/src/asset/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct AssetConfig {
pub(crate) headers: Option<HeadersConfig>,
pub(crate) ignore: Option<bool>,
pub(crate) enable_aliasing: Option<bool>,
#[derivative(Default(value = "Some(false)"))]
#[derivative(Default(value = "Some(true)"))]
pub(crate) allow_raw_access: Option<bool>,
}

Expand All @@ -35,7 +35,7 @@ pub(crate) struct CacheConfig {
}

fn default_raw_access() -> Option<bool> {
Some(false)
Some(true)
}

/// A single configuration object, from `.ic-assets.json` config file
Expand Down Expand Up @@ -931,7 +931,7 @@ mod with_tempdir {
.get_asset_config(assets_dir.join("index.html").as_path())
.unwrap(),
AssetConfig {
allow_raw_access: Some(false),
allow_raw_access: Some(true),
..Default::default()
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ pub struct StableState {

impl Asset {
fn allow_raw_access(&self) -> bool {
self.allow_raw_access.unwrap_or(false)
self.allow_raw_access.unwrap_or(true)
}

fn update_ic_certificate_expressions(&mut self) {
Expand Down
8 changes: 6 additions & 2 deletions src/canisters/frontend/ic-certified-assets/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1601,7 +1601,9 @@ mod allow_raw_access {
"https://a-b-c.ic0.app/page"
);

state.create_test_asset(AssetBuilder::new("/page2.html", "text/html"));
state.create_test_asset(
AssetBuilder::new("/page2.html", "text/html").with_allow_raw_access(Some(false)),
);
let response = state.fake_http_request("a-b-c.raw.icp0.io", "/page2");
dbg!(&response);
assert_eq!(response.status_code, 308);
Expand All @@ -1610,7 +1612,9 @@ mod allow_raw_access {
"https://a-b-c.icp0.io/page2"
);

state.create_test_asset(AssetBuilder::new("/index.html", "text/html"));
state.create_test_asset(
AssetBuilder::new("/index.html", "text/html").with_allow_raw_access(Some(false)),
);
let response = state.fake_http_request("a-b-c.raw.icp0.io", "/");
dbg!(&response);
assert_eq!(response.status_code, 308);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// See: https://github.com/WebAssembly/content-security-policy/blob/main/proposals/CSP.md.
// - We added img-src data: because data: images are used often.
// - frame-ancestors: none mitigates clickjacking attacks. See https://owasp.org/www-community/attacks/Clickjacking.
"Content-Security-Policy": "default-src 'self';script-src 'self' 'unsafe-eval';connect-src 'self' https://icp0.io https://*.icp0.io;img-src 'self' data:;style-src * 'unsafe-inline';style-src-elem * 'unsafe-inline';font-src *;object-src 'none';base-uri 'self';frame-ancestors 'none';form-action 'self';upgrade-insecure-requests;",
"Content-Security-Policy": "default-src 'self';script-src 'self' 'unsafe-eval';connect-src 'self' https://icp0.io https://*.icp0.io https://icp-api.io;img-src 'self' data:;style-src * 'unsafe-inline';style-src-elem * 'unsafe-inline';font-src *;object-src 'none';base-uri 'self';frame-ancestors 'none';form-action 'self';upgrade-insecure-requests;",

// Security: The permissions policy disables all features for security reasons. If your site needs such permissions, activate them.
// To configure permissions go here https://www.permissionspolicy.com/
Expand All @@ -50,7 +50,8 @@
// See: https://owasp.org/www-community/attacks/xss/
"X-XSS-Protection": "1; mode=block"
},
// redirect all requests from .raw.icp0.io to .icp0.io (this redirection is the default)
"allow_raw_access": false
// Set the allow_raw_access field to false to redirect all requests from .raw.icp0.io to .icp0.io
// The default behavior is to allow raw access.
// "allow_raw_access": true
},
]
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// See: https://github.com/WebAssembly/content-security-policy/blob/main/proposals/CSP.md.
// - We added img-src data: because data: images are used often.
// - frame-ancestors: none mitigates clickjacking attacks. See https://owasp.org/www-community/attacks/Clickjacking.
"Content-Security-Policy": "default-src 'self';script-src 'self' 'unsafe-eval';connect-src 'self' https://icp0.io https://*.icp0.io;img-src 'self' data:;style-src * 'unsafe-inline';style-src-elem * 'unsafe-inline';font-src *;object-src 'none';base-uri 'self';frame-ancestors 'none';form-action 'self';upgrade-insecure-requests;",
"Content-Security-Policy": "default-src 'self';script-src 'self' 'unsafe-eval';connect-src 'self' https://icp0.io https://*.icp0.io https://icp-api.io;img-src 'self' data:;style-src * 'unsafe-inline';style-src-elem * 'unsafe-inline';font-src *;object-src 'none';base-uri 'self';frame-ancestors 'none';form-action 'self';upgrade-insecure-requests;",

// Security: The permissions policy disables all features for security reasons. If your site needs such permissions, activate them.
// To configure permissions go here https://www.permissionspolicy.com/
Expand All @@ -50,7 +50,8 @@
// See: https://owasp.org/www-community/attacks/xss/
"X-XSS-Protection": "1; mode=block"
},
// redirect all requests from .raw.icp0.io to .icp0.io (this redirection is the default)
"allow_raw_access": false
// Set the allow_raw_access field to false to redirect all requests from .raw.icp0.io to .icp0.io
// The default behavior is to allow raw access.
// "allow_raw_access": true
},
]
Binary file modified src/distributed/assetstorage.wasm.gz
Binary file not shown.

0 comments on commit 6be85a4

Please sign in to comment.