-
Notifications
You must be signed in to change notification settings - Fork 582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NIP-05 should allow redirections #1544
Comments
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:
|
Lightning Address initially didn't support redirects because redirects are dangerous and insane, but people started implementing redirect support and the protocol had to bend. Arguably UX was greatly favored there because Lightning Address URLs are inherently dynamic -- i.e. you had to have a server there on your |
What is your goal here? Why do you need redirects? Why can't you just return your desired response from a Next.js API handler? If you don't have the user information in there you can fetch it from the other place that has the information at runtime and return it in any way you want, you can probably even just do something in a single line, like
Proxying a request is different than returning redirect responses. In the redirect case the target server will be hit by multiple HTTP requests from many different clients. In the proxy case all requests will be coming from your IP. |
Hi @fiatjaf, happy to see you joining the conversation
This is subjective and not an argument for protocol specification as it doesn't explain why it would be dangerous or insane in the context of NIP-05.
The redirect of the .well-known for LN addresses is mainly for aesthetic reasons as the response of the well-known endpoint includes a
I would argue that the vast majority of Nostr users use a service for NIP-05, among my contacts, I see countless
My goal is to redirect the calls from
The specification defines how the server behaves when receiving a request and how the client does when sending one. The specification is agnostic to the number of requests or the number of different clients the server allows. You could add a recommendation like "Servers SHOULD return a My point is that, similarly to firewalls, it's good to start by closing the doors and slowly open them if there is a clear use case or advantage. Like to LN Addresses, nothing inherent with redirects increases the attack surface and allowing them increases UX and ease of development. |
It looks like you don't really have a justification for this change since you are already doing what the NIP specifies and proxying requests in your server (with no harm to yourself or anyone) and you have cited no other use cases that would need the client-side redirects. |
I think I gave some justifications:
What I want to do by simply setting a redirect in the config of NextJS, outside of the redirects: async () => {
return [
{
source: '/.well-known/nostr.json',
destination: 'https://api.numeraire.tech/.well-known/nostr.json',
permanent: true,
},
];
}, What I have to do (implement a manual interceptor that could very well not behave as expected in the import type { NextApiRequest, NextApiResponse } from 'next';
export default async (req: NextApiRequest, res: NextApiResponse) => {
const { method, query } = req;
const backendUrl = new URL('https://api.numeraire.tech/.well-known/nostr.json');
for (const key in query) {
const value = query[key];
if (Array.isArray(value)) {
value.forEach(val => {
backendUrl.searchParams.append(key, val);
});
} else if (typeof value === 'string') {
backendUrl.searchParams.append(key, value);
}
}
try {
const response = await fetch(backendUrl.toString(), {
method,
headers: {
'Content-Type': 'application/json',
},
});
const data = await response.json();
res.setHeader('Cache-Control', 's-maxage=60, stale-while-revalidate=30, stale-if-error=600');
res.status(response.status).json(data);
} catch (error) {
console.error('Error fetching from backend:', error);
res.status(500).json({ error: 'Internal server error' });
}
} and rewrites: async () => {
return [
{
source: '/.well-known/nostr.json',
destination: '/api/nostr',
},
];
}, The handler is a manual implementation that differs in each framework. Given that you personally don't like redirects, maybe @dennisreimann from BTCPayServer having written the tutorial about redirects for LN addresses will have some insights. |
Sorry, but points 1, 2 and 3 are not justifications for adding a new breaking change to the protocol, they are just arguments about why past decisions might have not been based on the most solid arguments. We can argue that all day, but even if we conclude you are right these things will not justify making a change now. To justify making a change we would need an actual positive justification, like a real world valuable use case that isn't possible today. Point 4 is just telling me that it took you extra code to implement the handler in Next.js? That is already built already though, and changing it now would be extra work for you. Also, if it's just a static set of pubkeys that you have there wouldn't it make more sense to serve them directly from the Next.js app?
I don't get this point. Why do these users have care about your suggested change? |
If you allow redirects now, most clients will not follow them so they will be useless. This ship has already sailed. |
It is not a breaking change to the protocol. In the same way as you should not forbid redirections (a specific aspect of the HTTP protocol) on the Nostr protocol, you should not enforce redirections neither. Clients should be free to follow redirects if they want to. Removing the section about "security constraints" (that has nothing to do with security) will not break consensus. The use case is clear. I want to specify that a specific queried resource is permanently (301) or temporarily (302) available at a different location. Here a subdomain. That is what HTTP redirects are for and Nostr has no business in that context. We are not serving a static file. We are building the Numeraire SwissKnife, a lightning wallet similar to Alby Hub allowing creating LN and Nostr addresses, we propose it as a service through a dashboard. You can see the docs at docs.numeraire.tech and reach the API at api.numeraire.tech. the nextJS website at the root domain (numeraire.tech) should not be aware of Nostr. We are talking about protocol design here. Whether or not clients have already blocked redirections by following the NIP is irrelevant to the NIP itself, it will simply become an opinionated choice for clients. In definitive, I'm just trying to point out a flaw in the NIP design, if you don't want to change it because you don't like redirects, do as you please. |
Hi @fiatjaf,
The NIP-05 specification contains the following security constraint:
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:
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:
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 atapi.numeraire.tech
orapi.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.
The text was updated successfully, but these errors were encountered: