brave / brave-browser

Brave browser for Android, iOS, Linux, macOS, Windows.
https://brave.com
Mozilla Public License 2.0
17.63k stars 2.3k forks source link

IPNS names have dots converted to dashes. #36368

Closed MicahZoltu closed 1 month ago

MicahZoltu commented 7 months ago

May be related to #13303

Description

When accessing an ipns:// URL, Brave converts it into a subname that uses dashes instead of dots, even though this isn't necessary.

Steps to Reproduce

  1. Navigate to ipns://2.horswap.eth
  2. Open browser console and type window.location.href
  3. Notice that the result is http://2-horswap-eth.ipns.localhost:48084/ rather than ipns://2.horswap.eth (reported in #13303) but it is also not http://2.horswap.eth.ipns.localhost:48084/ (this bug report).

Actual result:

http://2-horswap-eth.ipns.localhost:48084/

Expected result:

http://2.horswap.eth.ipns.localhost:48084/

Reproduces how often:

Brave version (brave://version info)

1.63.162 Chromium: 122.0.6261.69 (Official Build) (64-bit)

Version/Channel Information:

Other Additional Information:

Miscellaneous Information:

Of note: If you navigate to http://2.horswap.eth.ipns.localhost:48084/ directly, your address bar will update to display ipns://2.horswap.eth, but window.location.href will now correctly show http://2.horswap.eth.ipns.localhost:48084/ (without the dashes). You can also see in the

Looking at the network log, it appears the problem is that ipns://2.horswap.eth is resulting in a request to http://localhost:48084/ipns/2.horswap.eth/, rather than a request to http://2.horswap.eth.ipns.localhost:48084/, and the backing IPFS gateway then redirects to the dashed URL. I believe the more correct thing to do here is to go directly to the subdomain origin, rather than starting with path routing and then letting the gateway redirect you to the subdomain.

diracdeltas commented 7 months ago

I think this is following the subdomain inlining behavior described in https://specs.ipfs.tech/http-gateways/subdomain-gateway/.

MicahZoltu commented 7 months ago

I think this is following the subdomain inlining behavior described in https://specs.ipfs.tech/http-gateways/subdomain-gateway/.

I believe the rules defined in 2.1.1 are specifically for converting between IPNS-in-path to IPNS-in-subdomain. IIUC, this is necessary because we cannot be sure that the IPNS name in the path is actually valid as a hostname. However, in this case we are starting with an IPNS hostname, so there is no worry about it being an invalid hostname, thus we don't need to convert.

We can gain confidence in this by the fact that the official IPFS gateway will not redirect subdomains with dots to subdomains with dashes.

cypt4 commented 7 months ago

Single-label form allows us to separate storages between different sites loaded on local node. Since ipns.localhost is eTLD a.ipns.locahost and b.ipns.localhost don't intersect. But x.a.ipns.locahost and y.a.ipns.locahost may intersect since site would be a.ipns.localhost in both cases. Related changes were done here for example. For this issue we should redirect http://2.horswap.eth.ipns.localhost:48084/ to http://2-horswap-eth.ipns.localhost:48084/ actually.

MicahZoltu commented 7 months ago

Hmm, my understanding was that the same-origin with regards to storage/cookies policy applied to the full host as described in https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#cross-origin_data_storage_access.

It sounds like perhaps you are using same-site, rather than same-origin, which feels wrong for origin isolation especially given the warning in the spec suggesting one shouldn't do that https://html.spec.whatwg.org/multipage/browsers.html#sites

Specifications should prefer the origin concept for security decisions. The notion of "public suffix" and "registrable domain" cannot be relied-upon to provide a hard security boundary, as the public suffix list will diverge from client to client. Specifications which ignore this advice are encouraged to carefully consider whether URLs' schemes ought to be incorporated into any decisions made, i.e. whether to use the same site or schemelessly same site concepts.

However, if you are using registrable domains for separation rather than same-origin, then I think everything below .eth should be considered registrable for the sake of registrable domain checking. This is because ENS is a hierarchical name system where one can register abc.eth and then open up subnames of abc.eth to the public for further registration. If someone registers xyz.abc.eth they can then open that up to further subname registration. This means that every subname (all the way down) is "registerable" for the sake of registrable name checking.

Of course, things get complicated when you are referring to something like ENS as a subdomain of an IPNS gateway, because in theory the gateway (cf-ipfs.com) is the registerable name, but that site is then serving registeralbe names underneath its ipns subdomain.

Perhaps the right solution here is to fix #13303 so when you navigate to ipns://some.example.eth it doesn't have a weird mix of IPNS + ENS + DNS and you can then unambiguously treat everything under .eth as registerable.

Alternatively, perhaps don't use registerable names for isolation? I'm guessing there is a spec out there somewhere that I can't find that says you should, but that seems crazy to me, and MDN seems to agree that isolation should be origin based, not registerable domain based.

lidel commented 7 months ago

Current behavior: ipns:// origins do not depend on each other

My understanding is that inlining of DNSLink names on localhost is intended behavior introduced in brave-browser#22927: Unify IPFS DNSLink behaviors for local and public gateway.

Brave sets Gateway.PublicGateways: InlineDNSLink to true to simplify internal security model and have window.location.origin constructed with the same convention on both localhost and public subdomain gateways like dweb.link.

Inlining of DNSLink names removes dependency of *.ipns Origins on DNS and public suffix list. Origin space is no longer hierarchical, it is flattened. Each content root, no matter if it is cryptographic IPNS Record, or DNSLink, is in its own unique origin without any parent/sibling relationship.

Next step: native ipns:// in window.location.origin and specs

I agree with @MicahZoltu that if Brave wants to change something, it should work towards window.location.origin using native ipfs:// and ipns:// (https://github.com/brave/brave-browser/issues/13303).

Why? Once we are on ipns://, we are no longer beholden to implementing hierarchical Origins from https:// and can decide how Origins should work. There are two paths forward, but if you've read between lines, we are already on (B) (because of InlineDNSLink:true, identifiers are opaque):

A specification for Origins on ipns:// is yet to be written, but my personal opinion is that "opaque authority" (B) serves the decentralized ecosystem better, as it does not require implementers such as Brave to worry about the nature of identifiers being CID or DNS, and hardcoding public suffix lists, etc to handle DNS "correctly". Opaque authority makes Origin isolation is stronger, and implementation becomes less complex.

TLDR suggestion is:

vadimstruts commented 1 month ago

The IPFS local node and scheme has been deprecated