nostr-protocol / nips

Nostr Implementation Possibilities
2.37k stars 570 forks source link

NIP-05 should allow redirections #1544

Open darioAnongba opened 3 hours ago

darioAnongba commented 3 hours ago

Hi @fiatjaf,

The NIP-05 specification contains the following security constraint:

The /.well-known/nostr.json endpoint MUST NOT return any HTTP redirects. Fetchers MUST ignore any HTTP redirects given by the /.well-known/nostr.json endpoint.

I would like to discuss why this constraint may not be appropriate in the context of NIP-05 and propose allowing redirections. Additionally, I will explain how preventing redirections diminishes the ease of implementation.

The problem

NIP-05 prohibits HTTP redirections by specifying that clients must not follow 301/302 redirects from the /.well-known/nostr.json endpoint, citing security concerns.

The security rationale

The NIP does not explain the specific security risks associated with allowing redirects. Generally, preventing clients from following redirects is intended to mitigate risks such as users being redirected to unexpected or unsafe locations if a domain is compromised.

However, in the context of NIP-05, clients trust the domain owner to provide the mapping from the Nostr identifier to the public key. The goal of NIP-05 is to facilitate this lookup, not to verify the authenticity of the information provided. Therefore, if a domain is compromised, disallowing redirects does not enhance security, as the trust has already been broken. A malicious domain could provide incorrect mappings regardless, and since there is no central authority to verify the information, the client’s trust in the domain is fundamental.

Reverse proxy VS HTTP redirection

In the context of NIP-05, HTTP redirects are functionally equivalent to reverse proxy configurations. The primary difference is that with reverse proxies, the user is unaware of the redirection and remains on the same domain, whereas with HTTP redirects, the client is informed to fetch the resource from a different location. Disallowing HTTP redirects while permitting reverse proxies seems unjustified, as both achieve the same result.

A reverse proxy configuration might look like this, effectively allowing redirects for Nostr addresses:

server {
    server_name mydomain.com;

    location / {
        proxy_pass http://api.mydomain.com;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

However, many modern deployment platforms like Vercel or DigitalOcean App Platform do not allow configuring reverse proxies directly. Developers using these platforms find it easier to implement an HTTP redirect, such as in Next.js:

// next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/.well-known/nostr.json',
        destination: 'https://api.mydomain.com/.well-known/nostr.json',
        permanent: true,
      },
    ];
  },
};

Preventing HTTP redirects forces developers to implement workarounds to intercept and forward the request to the backend, which is essentially the purpose of HTTP redirects.

Comparing with Lightning Address

Notably, most wallets that implement Lightning Addresses—such as Wallet of Satoshi, Alby, Breez, Blink, Phoenix, and others—allow HTTP redirects, despite the protocol having arguably higher security risks due to its transactional nature.

In practice, Lightning Address servers are often deployed on subdomains different from the root domain. For example, BTCPayServer instances are frequently hosted at pay.mydomain.com, and companies like Numeraire or Alby expose their APIs at api.numeraire.tech or api.getalby.com. There's even a tutorial in the BTCPayServer documentation recommending developers implement a redirect for LN Addresses here.

Proposed Change

NIP-05 should permit HTTP redirects, especially redirects to subdomains. Allowing HTTP redirects would simplify implementation for developers using platforms that do not provide access to reverse proxy configurations. Permitting redirects in this context would not increase the attack surface for NIP-05, as clients already trust the domain to provide accurate mappings.

vitorpamplona commented 2 hours ago

For reference, NIP-05 redirects because of this discussion https://github.com/nostr-protocol/nips/issues/127 and this PR https://github.com/nostr-protocol/nips/pull/128

darioAnongba commented 1 hour ago

Thanks for the reference, I see that the rationale leading to the decision is not very solid. It is somehow trying to prevent DDoS by forbidding redirects, but:

  1. You can redirect with reverse proxy to an external server:

    server {
    listen 80;
    server_name mydomain.com;
    
    location = /.well-known/nostr.json {
        proxy_pass https://mydifferentdomain.com;
        proxy_set_header Host mydifferentdomain.com;
    }
    }
  2. To prevent a high amount of requests to a server, you usually implement a caching mechanism, respected by most CDNs. The nostr.json is not supposed to change often so just cache for some time. The requests won't even hit your server:

    'Cache-Control', 's-maxage={seconds}, stale-while-revalidate={seconds}, stale-if-error={seconds}'
  3. Allowing redirects to same subdomain should at least be allowed since I am not targeting domain that I do not control. But again, reverse proxy redirects break this argument.

  4. It is not a security issue as there is no security involved in NIP-05. There is no risk of hacking, nor funds are risk and the data is public by definition.

  5. It is a subjective matter. Some servers might actually like being pointed to and provide the NIP-05 service to others.