nostr-protocol / nips

Nostr Implementation Possibilities
2.29k stars 559 forks source link

Kind 0 website drama #1253

Open alexgleason opened 3 months ago

alexgleason commented 3 months ago

NIP-24 states that website is "a web URL related in any way to the event author"

A valid URL must have a protocol like https.

But many clients let the user treat it as free-form text. They insert something like { "website": "fiatjaf.com" } into the metadata.

Are these clients wrong? To prevent protocol bloat, should we refuse to render these links? Or should we try to fix them by adding https in the front?

Ideally clients would just enforce them as URLs. Then they can display the URL however they want.

alexgleason commented 3 months ago

Here is the problem. Some sanitization is required. Because you potentially open the door to XSS if you stick the website into a web UI like this:

<a href={website}>{{website}}</a>

If the metadata is:

{ "website": "javascript:alert('pwned')" }

this will actually render and execute arbitrary JavaScript code.

So, due to the fact we cannot just be lazy about this, a decision needs to be made.

Do we take the path of the warlord and destroy all invalid websites? Or the path of the redeemer and try to fix them? What do you expect as a developer when you use a library like Nostrify and try to access the website field? Is it undefined unless it's a valid URL?

staab commented 3 months ago

I think postell's law applies here. You have to sanitize it anyway, so you might as well also slap a protocol on the beginning too. Same thing with relay url normalization.

fiatjaf commented 3 months ago

Postel's law is evil and doesn't apply anywhere ever, but this is such a minor thing I won't quibble. I do think it's a useless tag and people with websites can just write them in the description.

alexgleason commented 3 months ago

I ended up rejecting website's that aren't valid URLs. Clients can let you enter example.com into the box, but they need to convert it to https://example.com before signing the event.

fiatjaf commented 3 months ago

I ended up rejecting website's that aren't valid URLs.

Awesome, this is the best way to do it.

melvincarvalho commented 3 months ago

NIP-24 states that website is "a web URL related in any way to the event author"

NIP-24 is slightly under specified, right now

Postel's law is evil and doesn't apply anywhere ever

It's not that evil, it allows large chunks of the web to have a good UX. The truth is that data is messy, especially when there's no validation required.

You have to sanitize it anyway

Yes you should sanitize

A website should be a URI, and URIs can be absolute or relative. In this case, relative doesnt make much sense, because there's not an immediately obvious @base.

So we may assume an absolute URI conforming to RFC3986.

I ended up rejecting website's that aren't valid URLs.

Safest approach, or use a regex. But that may break many profiles.

In general, each field in NIP-24 can have a human readable description and a flag stating whether or not it's a URI. This is important because having URIs in data is useful as exemplified by "A" tags in HTML, <> syntax in turtle, but JSON has no equivalent syntax (unfortunately!).

What might be helpful is if I extend the nostr ontology to include all the field in NIP-24, and ensure website is a URI. Which is the same standard used in ActivityPub, schema.org etc.

https://w3id.org/nostr

That could also open the door to a bit more interop and extensibility to NIP-24