Potential Redirect Issue with "allow_raw_access: false" in .ic-assets.json5

Deploying the asset canister with the setting “allow_raw_access: false” does not produce the desired result: the browser does not redirect from the URL “https://canisterId.raw.icp0.io” to “https://canisterId.icp0.io”.

This used to work a couple of months ago.

The .ic-assets.json5 file contains custom headers, and they are being sent to the browser — which means the file is being processed.

Is this a temporary issue?

@peterparker @Severin Could you please tag someone who might be able to help? Thanks

So, I don’t know the answer - that’s why I didn’t reply earlier - since I don’t use DFX myself. In Juno, there is an option for raw, but it’s intentionally undocumented because I believe it’s an insecure and bad practice to use it.

The best person to answer your question is Severin, whom you already tagged. I think he’s out of the office today, but he’ll probably see the notification next time he’s around. If you don’t get an answer after few days, feel free to resurface the question.

1 Like

Thanks for the reply.

Yes, I do want the “raw” version to be inaccessible, but for some reason, after deploying the new canister, the redirect doesn’t work.

I’ll be waiting for a response from Severin.

Is this a fresh deployment or did you update an existing deployment? dfx sometimes has issues updating metadata like headers or this setting. If you tried to update an existing deployment, would you mind trying to upgrade the canister with --mode reinstall?

1 Like

This canister was created by the code from another canister one week ago. Then I uninstalled this canister using “dfx”. Then deployed asset canister using “dfx deploy…”

FYI: adding new custom header to .ic-assets.json5 file and redeploying - takes effect - browser immediately receives new header.

Reinstalled with --mode reinstall - still getting Status 200 (not redirect) for “raw” url :man_shrugging:

Dear @Severin - any ideas?

Sorry, got overwhelmed by my todo list. I would like to narrow the issue down if the problem is with updating the setting, or with doing the redirect.

If you call get_asset_properties with argument ("<path to a file>") on the asset canister, what does it report for allow_raw_access (maybe displayed as 3_021_287_825)? Is it null, or what does the setting say?

Calling dfx canister --network ic_test call CANISTER_ID get_asset_properties '("/index.html")' - output is:

(
  record {
    headers = opt vec {
      record {
        "Strict-Transport-Security";
        "max-age=31536000; includeSubDomains";
      };
      record { "X-XSS-Protection"; "1; mode=block" };
      record { "Referrer-Policy"; "same-origin" };
      record {
        "Content-Security-Policy";
        "default-src \'self\';script-src \'self\';connect-src \'self\' http://localhost:* 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;";
      };
      record { "X-Content-Type-Options"; "nosniff" };
      record { "X-Frame-Options"; "DENY" };
      record {
        "Permissions-Policy";
        "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=()";
      };
    };
    is_aliased = null;
    allow_raw_access = opt false;
    max_age = null;
  },
)

Content of .ic-assets.json file:

[
  {
    "match": "**/*",
    "security_policy": "standard",
    "allow_raw_access": false
  },
  {
    "match": ".well-known",
    "ignore": false
  },
  {
    "match": ".well-known/ii-alternative-origins",
    "headers": {
      "Access-Control-Allow-Origin": "*",
      "Content-Type": "application/json"
    },
    "ignore": false
  }
]

Well… I’m pretty stumped on this one. allow_raw_access = opt false; in the output of get_asset_properties means that the setting is applied correctly. Given this logic, if the setting is correct and the request is recognized as coming from raw then redirection should happen. Nothing about the logic to detect raw has changed. I just asked internally and the Host header gets passed correctly (EDIT: nevermind, probably not). We have tests that verify that redirection works.

What URL do you use to make the raw request? Would you mind sharing the full link? DM is fine too.

Apparently the Host header (which the asset canister relies on for detecting if the request is coming from .raw) is only passed in HTTP1 requests, but not HTTP2. So under HTTP2 canisters have no way to figure out if a request is coming from raw or not. The boundary node team will discuss options and I will do my best to think of reporting back here.

1 Like

Hello @Severin
Any news regarding HTTP2 requests?
Thanks

1 Like

Thanks for the ping, I heard that a workaround is implemented and deployed on the boundary nodes. It should work again.

Still does not work.

My canister is on a subnet opn46-zyspe-hhmyp-4zu6u-7sbrh-dok77-m7dch-im62f-vyimr-a3n2c-4ae.

(
  record {
    headers = opt vec {
      record { "Referrer-Policy"; "same-origin" };
      record { "X-Content-Type-Options"; "nosniff" };
      record {
        "Content-Security-Policy";
        "default-src \'self\';script-src \'self\';connect-src \'self\' http://localhost:* 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;";
      };
      record {
        "Permissions-Policy";
        "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=()";
      };
      record { "X-XSS-Protection"; "1; mode=block" };
      record { "Cache-Control"; "no-cache" };
      record { "X-Frame-Options"; "DENY" };
      record {
        "Strict-Transport-Security";
        "max-age=31536000; includeSubDomains";
      };
    };
    is_aliased = null;
    allow_raw_access = opt false;
    max_age = null;
  },
)

Also OpenChat https://6hsbt-vqaaa-aaaaf-aaafq-cai.raw.icp0.io/ has no redirect.

Hi @Severin, just checking in — have there been any updates regarding the issue?

It’s still not working on my end. OpenChat https://6hsbt-vqaaa-aaaaf-aaafq-cai.raw.icp0.io/ also still lacks a redirect.

Would appreciate any news when you have a moment. Thanks!

Someone on the boundary node team wanted to investigate again but was probably distracted. I’ll ping them again

1 Like

Hey @pixld8ta

sorry for the late reply. We have added a fix to the HTTP gateway to inject the host header in case it is missing (this is the case for HTTP2 as it doesn’t use the host header, but the authority). I made a local test with the following two commands:

$ curl -sLv -X GET \
    --resolve oa7fk-maaaa-aaaam-abgka-cai.ic0.app:443:212.71.124.186 \
    https://oa7fk-maaaa-aaaam-abgka-cai.ic0.app/
    
$ curl -sLv --http2 -X GET \
    --resolve oa7fk-maaaa-aaaam-abgka-cai.ic0.app:443:212.71.124.186 \
    https://oa7fk-maaaa-aaaam-abgka-cai.ic0.app/

How do you test it?