Skip to content

Add filehost#562

Open
emersion wants to merge 1 commit intoircv3:masterfrom
emersion:filehost
Open

Add filehost#562
emersion wants to merge 1 commit intoircv3:masterfrom
emersion:filehost

Conversation

@emersion
Copy link
Contributor

@emersion emersion commented Apr 6, 2025

This is shipped by soju + gamja + goguma + senpai as a vendored spec, and is based on an earlier draft by @progval.

Comment on lines +36 to +39
When clients wish to upload a file using the server's recommended service, they
can send a request to the upload URI. The request method MUST be POST. Clients
SHOULD authenticate their HTTP request with the same credentials used on the
IRC connection (e.g. HTTP Basic for SASL PLAIN, HTTP Bearer for SASL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spirit of my draft was that servers would embed credentials in the URL, to allow uploading to third-party services. With your design, third-party services get connection credentials that are valid for the IRCd in the most common SASL scheme (PLAIN).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This is an intentional design decision. The filehost server can forward the request to another server if need be.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but it still knows the password

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand?

What I meant is that the filehost server can be hosted by the same folks as the IRC server, can check the credentials in the request, and can forward requests without IRC credentials to another server if need be.

Here's why I deviated from your proposal:

  1. Putting secrets in URLs is a bit scary. ISUPPORT is in general not security-sensitive.
  2. The upload service cannot be any random third-party: it needs to implement the spec's endpoints. In general, third-party upload services have a custom API.
  3. With your proposal, the external service still needs to be somehow tied to the IRC server to check the credentials embedded in the request URL. Credentials need to be per IRC connection. With signed tokens you hit issues regarding revocation etc.
  4. It resulted in a lot of additional complexity in my server implementation. On the other hand, proxying is very simple (and implemented in soju).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is that the filehost server can be hosted by the same folks as the IRC server

My point was that it doesn't have to be.

The upload service cannot be any random third-party: it needs to implement the spec's endpoints.

There's no endpoint, it's just a URL that accepts generic HTTP POST

With your proposal, the external service still needs to be somehow tied to the IRC server to check the credentials embedded in the request URL.

My thinking was that the IRC server would create token on the external service, not the other way around.

Putting secrets in URLs is a bit scary. ISUPPORT is in general not security-sensitive.

It resulted in a lot of additional complexity in my server implementation. On the other hand, proxying is very simple (and implemented in soju).

Those however, are good points. I'm sold.

@bb010g
Copy link

bb010g commented Jan 4, 2026

This is missing the normal draft/ prefix warning section:

Notes for implementing work-in-progress version

This is a work-in-progress specification.

Software implementing this work-in-progress specification MUST NOT use the unprefixed FILEHOST isupport token. Instead, implementations SHOULD use the draft/FILEHOST isupport token to be interoperable with other software implementing a compatible work-in-progress version.

The final version of the specification will use an unprefixed isupport token.

This absence has already led to ObsidianIRC jumping the gun: https://github.com/ObsidianIRC/ObsidianIRC/blob/9632acfb35cbd208bfc94e66d5e2882f47ef58ec/src/protocol/isupport.ts#L64

    if (key === "FILEHOST" || key === "draft/FILEHOST") {

@ValwareIRC
Copy link
Contributor

This is missing the normal draft/ prefix warning section:

Notes for implementing work-in-progress version

This is a work-in-progress specification.

Software implementing this work-in-progress specification MUST NOT use the unprefixed FILEHOST isupport token. Instead, implementations SHOULD use the draft/FILEHOST isupport token to be interoperable with other software implementing a compatible work-in-progress version.

The final version of the specification will use an unprefixed isupport token.

This absence has already led to ObsidianIRC jumping the gun: https://github.com/ObsidianIRC/ObsidianIRC/blob/9632acfb35cbd208bfc94e66d5e2882f47ef58ec/src/protocol/isupport.ts#L64

    if (key === "FILEHOST" || key === "draft/FILEHOST") {

I think the reason for this, and the reason why ObsidianIRC supports both of these, is because supporting draft prefixes or vendor prefixes in ISUPPORT tokens is a relatively new relaxation of the requirements in the IRC protocol. This spec was drafted before that relaxation, and could still be updated to use the draft prefix.

@bb010g
Copy link

bb010g commented Jan 4, 2026

I think the reason for this, and the reason why ObsidianIRC supports both of these, is because supporting draft prefixes or vendor prefixes in ISUPPORT tokens is a relatively new relaxation of the requirements in the IRC protocol. This spec was drafted before that relaxation, and could still be updated to use the draft prefix.

This PR's 3108389a94 (committed 2025-04-06, the same day the PR was submitted) uses draft/FILEHOST. ObsidianIRC's 9632acfb35 was committed 2025-10-06 and decided to allow both draft/ prefixed and unprefixed from the start. soju has been using soju.im/FILEHOST since their b76cb6d5e6 (committed 2024-01-24). gamja has only supported prefixed (87e88cccca, committed 2024-04-16), and Goguma has only supported prefixed (894d93bb97, committed 2024-01-25). Prefixes in ISUPPORT tokens are at least 2 years old, and ObsidianIRC is the one differing from existing proposals & implementations here, at least as far as I can tell.

@ValwareIRC
Copy link
Contributor

ValwareIRC commented Jan 4, 2026

Prefixes in ISUPPORT tokens was a relaxation made in the past few months, maybe you're thinking of prefixed CAP tokens? There were prefixed ISUPPORT tokens in the wild, but at the time it was technically against the protocol, and it was in fact in part due to this specification that the whole thing was brought up and relaxed. ObsidianIRC opted to support both because, at the time, using prefixes on ISUPPORT tokens was against IRC protocol, but you are right that we should now be supporting only the prefixed version. At the time of implementing, it could have gone either way, which is why we support both.

@bb010g
Copy link

bb010g commented Jan 4, 2026

Ah, I had no idea the spec change there was so recent and that both soju and this proposal were previously out of compliance. Apologies.

@ValwareIRC
Copy link
Contributor

No need for apologies heh, thank you for your interest

@ValwareIRC
Copy link
Contributor

I think another thing was that there was prior art on the filehost spec from progval which didn't have the prefix in it, so relying on it being unprefixed to determine if it's a final version won't work so great.

Comment on lines +28 to +31
Its value MUST be a URI and SHOULD use the `https` scheme. Clients MUST ignore
tokens with an URI scheme they don't support. Clients MUST refuse to use
unencrypted URI transports (such as plain `http`) if the IRC connection is
encrypted (e.g. via TLS).
Copy link

@furudean furudean Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any actual relation between an IRC server's use of TLS vs insecure connection, and the accompanying upload server's connection protocol?

Many IRC networks provide insecure connections for wider client support. If a client is going to put in the effort today to implement draft/filehost, wouldn't it be more sensible to require HTTPS, given that we're sending credentials over the network? HTTPS is not hard to implement today, and I think we can make that requirement of a web server. Otherwise we encourage insecure practices for a brand new feature. Either that, or not be opinionated about what protocol is used to connect to the upload server.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any actual relation between an IRC server's use of TLS vs insecure connection, and the accompanying upload server's connection protocol?

Allowing insecure uploads when the user has set up a secure IRC connection is a kind of mixed content security issue. A user connecting via TLS wouldn't assume that their credentials get exposed via HTTP when uploading a file.

wouldn't it be more sensible to require HTTPS, given that we're sending credentials over the network?

There are uses for plaintext IRC connections which aren't compatibility with very old clients. For instance, during development, or over Tor, or on a private network (e.g. VPN).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These motivations make sense to me. Would it be a good idea to include them in the RFC? I could see others asking why it's that way otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually don't include design decision motivations in normative specs. Completely fine adding something if it's deemed better.

@classabbyamp
Copy link

not sure if it would count towards ratification, but I wrote a thing to use FILEHOST to proxy to various pastebins: https://github.com/classabbyamp/convoyeur

@emersion
Copy link
Contributor Author

emersion commented Jan 4, 2026

Added the prefix disclaimer.

bb010g added a commit to bb010g/ObsidianIRC that referenced this pull request Jan 27, 2026
bb010g added a commit to bb010g/ObsidianIRC that referenced this pull request Jan 27, 2026
as specified by the proposed draft since 2026-01-04

Link: ircv3/ircv3-specifications#562
@jwheare
Copy link
Member

jwheare commented Feb 10, 2026

Which servers support this so far?

@emersion
Copy link
Contributor Author

AFAIK soju only so far. Ergo has added a way to manually insert ISUPPORT tokens from the config file but that requires server operators to bring up a separate HTTP file upload server:

https://github.com/ergochat/ergo/blob/c79b65cf8ad25e77367c863f20ddf38cfeb52bf3/default.yaml#L401

@bb010g
Copy link

bb010g commented Feb 12, 2026

@emersion
Copy link
Contributor Author

This also merely advertises a new ISUPPORT token. What HTTP server implementation would a user point the URL to? (Seems like the documentation URL is a 404.)

@slingamn
Copy link
Contributor

Is there a reason this doesn't include HTTP DELETE (validated against the user's account name)? It could be an optional feature.

@emersion
Copy link
Contributor Author

We've considered adding more features, but to be usable in a modern multi-client context this would need a lot more. Probably would need a way to list a user's own uploads.

DELETE on its own would not be useful from my clients PoV.

@jwheare jwheare added this to the Roadmap milestone Feb 21, 2026
matheusfillipe pushed a commit to ObsidianIRC/ObsidianIRC that referenced this pull request Mar 2, 2026
as specified by the proposed draft since 2026-01-04

Link: ircv3/ircv3-specifications#562
@furudean
Copy link

When implementing support for this and soju.im/filehost in Halloy I raised a security concern:

I'm having second thoughts with sending the user's credentials and I'm strongly now leaning that this is a bad idea. A server being able to specify an ISUPPORT token for uploads (that may be mistakenly sent) is an abuse vector.

There are no semantics in draft/FILEHOST that defines how authentication should be made with the server. The non-normative example contains an Authorization header, but does not define how authentication should be done. soju.im/filehost on the other hand, does specify:

Clients SHOULD authenticate their HTTP request with the same credentials used on the IRC connection (e.g. HTTP Basic for SASL PLAIN, HTTP Bearer for SASL OAUTHBEARER).

It follows by implementation that soju's upload server does require credentials, or the request will fail.

The client should follow the semantics of the upload server, but this is not specified well for draft/FILEHOST. Guessing is a bad idea. We could dynamically activate send_credentials when soju.im/filehost and send credentials in that case, though I don't like this very much either.

I would prefer if it instead explicit in the config and then documented how to use this feature with soju instead. It's more to configure, but we avoid potentially leaking people's IRC credentials just for connecting.

As a result of this, I opted to not send the user's credentials by default in Halloy. I do not know concretely what sorts of changes should be made to the spec if any, but I figured I would at least raise my thoughts here to prompt discussion.

@sadiepowell
Copy link
Contributor

I have previously raised the idea of the server providing credentials to the user for the upload server. I still think this (as well as my proposal to formally require that upload servers use TUS) are a good idea.

@furudean
Copy link

@sadiepowell does tus provide additional security over regular uploads?

@sadiepowell
Copy link
Contributor

No, but its a standard system for handling resumable uploads which is better than the vibes-based approach in the current spec.

@furudean
Copy link

furudean commented Mar 21, 2026

Some relevant prior work here is Access-Control-Allow-Credentials. Similar problem, and the solution was that only the same origin may send credentials, otherwise they can't be used. This is an OK guarantee that your credentials don't leave the server you already trust. May or may not make sense for IRC.

@reesericci
Copy link

Just going to forward this contribution I made from the Halloy repo:


It might make sense here to have a standardized OAuth/OIDC-style handshake between the file hosting providers, the bouncer/server and the client. I'd be happy to write up an RFP to IRCv3 to add this as the standard if people would be interested. Here's a little mermaid diagram of how this could work:

sequenceDiagram
actor Client
participant Server
participant Filehost@{ "type": "database"}
	Filehost-->>Server: Requests OIDC configuration
	Server->>Filehost: Returns OIDC configuration with JWKS url
	Filehost-->>Server: Requests JSON Web Keyset (JWKS) to verify tokens issued by the server
	Server->>Filehost: Returns JWKS
	Client-->>Server: Establish connection
	Server->>Client: Advertises FILEHOST
	Client -->>Server: Requests access token
	Server -->>Filehost: Requests nonce and provides client IP address to expect upload from
	Filehost->>Server: Returns nonce (bound to client IP)
	Server->>Client: Returns signed JWT with expiration, nonce and hashed username as data
	Client->>Filehost: Sends file using multipart/form-data with key `file` and the JWT in the Authorization header
	Filehost->>Client: Verifies signature with cached JWKS, nonce, expiration, audience and if valid returns file URL
Loading

Originally posted by @reesericci in squidowl/halloy#1680 (comment)

@ValwareIRC
Copy link
Contributor

ObsidianIRC uses JWT >.>

@emersion
Copy link
Contributor Author

@furudean I don't understand your concern. The user already sends the credentials to the IRC server each time they connect. This spec makes it so clients also send credentials to the server-controlled upload endpoint. What is the threat model here? Why would a server send an untrusted ISUPPORT token?

There are no semantics in draft/FILEHOST that defines how authentication should be made with the server.

draft/FILEHOST in this PR has the same authentication requirements as soju.im/FILEHOST. (Note that unmerged specs are subject to breaking changes.)

@Celelibi
Copy link

I can't talk for @furudean but it makes sens to me to want to reduce the amount of credentials on the wire. And the filehost service doesn't necessarily lives on the same physical server as the IRCd. Not sending credentials to the filehost server could limit the impact of a compromised server.

@emersion
Copy link
Contributor Author

Credentials are transmitted every time a client connects anyways, so the benefit of skipping it when uploading is pretty low.

I agree that securing credentials in general is a good idea, but I think it would be worthwhile to improve that for the IRC connection too instead of limiting it to HTTP file upload. This is possible via multiple ways, e.g. #584 or OAuth2 with dynamic client registration.

@sadiepowell
Copy link
Contributor

Networks may want to offload file storage to a server which they do not control so I think it would be good to provide temporary tokens for use with the upload server.

@slingamn
Copy link
Contributor

My two cents: this specification works for the use cases it was intended for, and lacks features that would allow it to scale to a public network:

  • Token-based authentication (as per Sadie's suggestion that this facilitates using a file hosting server that is less trusted than the ircd)
  • File deletion and enumeration
  • Communicating limits and quotas to the user (individual file size limit, total upload limit)
  • Optionally, access controls for viewing the files (or some other mechanism to prevent use of the server for hosting malicious or illegal content)

I think it would be appropriate for this spec to coexist with a greenfield design that has hardening and additional features (I like Sadie's suggestion of tus.io).

@reesericci
Copy link

I agree that we should take steps towards supporting OpenID connect - it would provide us a solid foundation to build on. I think this filehost specification is a good place to start because IRCv3 file hosts don't currently exist (except Soju), so we can implement this however we'd like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.