chroma-core / chroma

the AI-native open-source embedding database
https://www.trychroma.com/
Apache License 2.0
15.63k stars 1.31k forks source link

[Feature Request]: Default to allowing localhost:3000 for CORS #1841

Open AlabasterAxe opened 8 months ago

AlabasterAxe commented 8 months ago

Describe the problem

When users are initially getting started with chromadb, it's easy to run into a situation where they attempt to use the JavaScript client in a browser context and their requests will fail with CORS errors if they haven't explicitly configured their local instance to accept requests from their localhost with the CHROMA_SERVER_CORS_ALLOW_ORIGINS.

Describe the proposed solution

By default, chroma run could accept requests from http://localhost:3000, which is what the example defaults to running at. Then, if we detect that the user hasn't overridden the default configuration, we'd print a noisy warning that user's should explictly configure their CORS settings before using this in a production system.

Alternatives considered

Just not do this: The current approach is to notify the user of the possibility that they could have a misconfigured CORS setting on the server if the request fails. That may be enough. That said, the risk of allowing only a single localhost authorized domain seems minimal. In order to have something malicious running on localhost, that would mean that an attacker already has the ability to run code on the person's machine at which point the correct cors configuration is not going to make that situation secure.

Importance

nice to have

Additional Information

No response

tazarov commented 8 months ago

@AlabasterAxe, thanks for this clarification. You are correct that if not configured, the user will get some weird error, especially on the client side (aka browser). It is important to observe that by default, Chroma does not define any CORS settings that will make all requests fail - that is secure by design.

I do not recommend changing that behavior. CORS is a dreaded topic for many users, and I'd take documentation over default config + warning message any day of the week. People putting Chroma into production should follow good practices and good documentation. Some of the users also do not read warning messages.

Do you have an observation where not having this default value causes overwhelming struggles for Chroma users? Could it be solved via docs? What assumptions are made that will be invalidated if a forward or a reverse proxy is put in front of Chroma (which most prod users should do?

AlabasterAxe commented 8 months ago

cc: @jeffchuber

Yeah ultimately this is about tradeoffs. I think the idea here is that it should be as frictionless as possible to get up and running with a Chroma example. As you say, CORS is a dreaded topic for many users so if we can avoid users having to debug CORS issues to get their Chroma dev setup working, that's preferrable.

I have to admit that I am not a security expert but my understanding is that the default CORS configuration of not allowing any cross-origin requests is to limit the ability for a bad actor at e.g. scam-domain.com to make requests to legitimate-domain.com, hijacking any cookies used for authentication. If localhost:3000 is the only allowed CORS origin, that would mean that an attacker would need to be running a malicious site on the users own machine (which, to be clear, doesn't seem out of the realm of possibility, but I would argue it significantly reduces the circumstances under which this would happen ).

I'm not sure how Chroma does authentication but if the Chroma client doesn't use cookies, then even if an attacker were able to make requests to an instance of Chroma, it wouldn't allow them to make requests on behalf of those users.

Ultimately, it's not clear to me that the negative security implications of allowing "localhost:3000" as an accepted request origin is that significant, but I'm happy to understand more about the threat model there!

tazarov commented 8 months ago

@AlabasterAxe, you have a point, but here's what I think might be a good approach in the order of appearance:

  1. Update docs to make people aware of the fact they need CORS config when using JS client in browser (with appropriate config to update
  2. Update docker/docker compose
  3. Update defaults in code

Also, here's the problem that this solves:

image

AlabasterAxe commented 8 months ago

Yeah that's a good callout! (and I love that diagram 😁)

I think calling it out in the docs is a reasonable compromise. I've also have this PR which explicitly calls out CORS as a potential issue in the error (Not to mention that the browser itself will show CORS errors) so hopefully there are enough touchpoints that users aren't completely lost.

jacobhq commented 4 months ago

Do you think it may be a good idea to add this to the troubleshooting section of the docs, as CORS often seems to bite people in general, and is something that's easy(ish) to check and fix if documented/mentioned. What do you all think? I'm happy to handle it in a PR if you think it'd be helpful!

tazarov commented 4 months ago

Do you think it may be a good idea to add this to the troubleshooting section of the docs, as CORS often seems to bite people in general, and is something that's easy(ish) to check and fix if documented/mentioned. What do you all think? I'm happy to handle it in a PR if you think it'd be helpful!

This makes sense. We have this - https://cookbook.chromadb.dev/strategies/cors/