Chainlit / chainlit

Build Conversational AI in minutes ⚡️
https://docs.chainlit.io
Apache License 2.0
7.16k stars 940 forks source link

User Sessions shared across multiple users behind Proxy or VPN #1407

Open dvdr00t opened 1 month ago

dvdr00t commented 1 month ago

Describe the bug
When multiple users access the Chainlit application from the same IP (e.g., when behind a proxy or VPN), the user_session is shared across those users, leading to data from one session being accessible by another. This results in a mixing of session data, causing unexpected behavior, such as retrieving or storing incorrect session-specific information.

To Reproduce
Steps to reproduce the behavior:

  1. Deploy a Chainlit application and expose a specifc port to the internet.
  2. Have two or more users access the application through a proxy or VPN (e.g., an office network).
  3. Each user sets and retrieves session-specific data using cl.user_session.set() and cl.user_session.get().
  4. Observe that session data from one user is accessible by another.

Expected behavior
Each user should have a unique session, even when accessing the application from the same IP address, ensuring that session-specific data remains private to each user.

Screenshots
If applicable, add screenshots to help explain the problem.

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context
The issue seems to stem from how user sessions are identified and stored. In the current setup, it appears that sessions are identified solely by the session ID, which may not be properly isolated for different users behind the same IP. As a result, users sharing the same IP (e.g., through a corporate proxy or VPN) can end up sharing the same session, causing a mix-up of session data.

dosubot[bot] commented 1 month ago

Hey @dvdr00t! I'm here to help you with any bugs, questions, or contributions you have for Chainlit. Let's squash those bugs together!

To ensure that each user has a unique session in a Chainlit application, even when multiple users access it from the same IP address through a proxy or VPN, you can rely on the context.session.id to uniquely identify each session. The UserSession class uses context.session.id to manage user-specific data, ensuring that each session is distinct and not shared across users.

Here's how you can achieve this:

Here's a code snippet demonstrating this approach:

user_sessions: Dict[str, Dict] = {}

class UserSession:
    def get(self, key, default=None):
        if not context.session:
            return default

        if context.session.id not in user_sessions:
            user_sessions[context.session.id] = {}

        user_session = user_sessions[context.session.id]
        return user_session.get(key, default)

    def set(self, key, value):
        if not context.session:
            return None

        if context.session.id not in user_sessions:
            user_sessions[context.session.id] = {}

        user_session = user_sessions[context.session.id]
        user_session[key] = value

Additionally, implementing authentication mechanisms such as password authentication, OAuth, or custom header authentication can enhance security and ensure unique user identification. By defining a CHAINLIT_AUTH_SECRET environment variable and using authentication callbacks, you can ensure that each user has a unique identifier, preventing data sharing across users [1][2][3].

To continue talking to Dosu, mention @dosu.