[Standards] XEP-0363: Restricted set of headers when requesting a slot
ivan at vucica.net
Tue Dec 15 01:56:33 UTC 2020
I'm trying to direct the chat client to talk directly to the cloud
storage API using 'signed URLs', granting time-restricted upload
access to possessing a URL, where I can still restrict file size.
The cloud storage API happens to be Google Cloud Storage, but to my
understanding, a similar approach applies to Amazon S3 and possibly
other similar stores.
The XEP says (https://xmpp.org/extensions/xep-0363.html#request):
The <put> element MAY also contain a number of <header> elements which
correspond to HTTP header fields. Each <header> element MUST have a
name-attribute and a content with the value of the header. Only the
following header names are allowed: Authorization, Cookie, Expires.
Other header names MUST be ignored by the requesting entity and MUST
NOT be included in the HTTP request. The requesting entity MUST strip
any newline characters from the header name and value before
performing the HTTP request.
I do understand that this tries to restrict the possible damage that a
compromised server could direct a chat client to execute.
However, this does mean setting useful custom headers such as
x-goog-acl becomes difficult. (This particular header's documentation:
- make the whole bucket public to the internet: in this particular
- on first GET access, update ACLs
- hopefully the API exists -- I did not actively seek it yet
- feasible because I want the permalink GET URLs to be on a domain I control
- downside: this does cost a small amount of money
The best option is for the chat client to set this header to value
"public" in order to make the blob visible to unauthenticated users.
This is only one cloud storage provider. It's not a lot of money to
perform an extra write operation when the GET method is executed by
the HTTP frontend (creating the 302 response). And clearly, this is a
proprietary header. So -- it's not a big deal.
But, I do wonder what attacks are even possible if arbitrary PUT
request headers are allowed. The user still has to attempt an upload,
so this wouldn't be a large distributed attack. What are the concerns
with the upload component directing the user to an arbitrary service
to perform the upload?
So what were the concerns with setting custom headers? What would it
take to add more headers to the allowlist?
Would it make more sense to *recommend* clients to *ask* the user to
one-time confirm the upload to a new domain, if the domain doesn't
match the server domain (i.e. storage.example.com vs
example-chat.org)? That way, there should be no concerns about which
headers the component requests the client to set.
More information about the Standards