nostr-protocol / nips

Nostr Implementation Possibilities
2.39k stars 577 forks source link

Clarify NIP-96 Authorization `payload` language #1376

Open Ademan opened 3 months ago

Ademan commented 3 months ago

At the time of writing (master = 8b75d7be7c45f5867ea6541095f7322fe7d77a26 ) NIP-96 says this about the Authorization header:

When indicated, clients must add an NIP-98 Authorization header (optionally with the encoded payload tag set to the base64-encoded 256-bit SHA-256 hash of the file - not the hash of the whole request body).

The bold section appears to me to contradict NIP-98 in two ways. NIP-98 says:

When the request contains a body (as in POST/PUT/PATCH methods) clients SHOULD include a SHA256 hash of the request body in a payload tag as hex (["payload", ""]), servers MAY check this to validate that the requested payload is authorized.

The NIP-96 language seems to me to contradict NIP-98 by

  1. encoding the payload hash as base64 instead of hex
  2. hashing the uploaded file only rather than the entire body

Resolving 1 seems trivial, use hex, not base64 for the payload hash.

2 is a bit more problematic, as the NIP-98 language is actually somewhat difficult to implement as specified. (You need to serialize the multipart/form-data which appears non-trivial in the browser)

If this discrepancy is intentional (to allow a NIP-96 server to accept an easier-to-generate hash, to avoid the problem with 2 as specified in NIP-98) then I suggest not using the payload tag to reduce ambiguity. Maybe use nip96_payload instead.

As a side note, I'm not sure which, if any, NIP-96 servers are actually validating the payload tag, as both nostr-tools, coracle, and I suspect others are accidentally hashing "{}" and so the payload tag is always 44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a regardless of the file payload.

Ademan commented 3 months ago

As pointed out in #1390 NIP-98 actually defines the payload tag as a "SHOULD" so it's TECHNICALLY not a contradiction to put any arbitrary data in payload.

I have to admit though, when I go back and read NIP-98 and I still read this:

When the request contains a body (as in POST/PUT/PATCH methods) clients SHOULD include a payload tag which must contain a SHA256 hash of the request body in a payload tag as hex (["payload", "<sha256-hex>"]), servers MAY check this to validate that the requested payload is authorized.

instead of what's actually written:

When the request contains a body (as in POST/PUT/PATCH methods) clients SHOULD include a SHA256 hash of the request body in a payload tag as hex (["payload", "<sha256-hex>"]), servers MAY check this to validate that the requested payload is authorized.