heimdall icon indicating copy to clipboard operation
heimdall copied to clipboard

Support for OAuth2-Proxy Cookie Splitting

Open aslafy-z opened this issue 1 year ago • 3 comments

Preflight checklist

  • [x] I agree to follow this project's Code of Conduct.
  • [x] I have read and am following this repository's Contribution Guidelines."
  • [x] I have discussed this feature request with the community.

Describe the background of your feature request

OAuth2-Proxy uses cookie splitting when session cookies exceed a certain size, breaking the authentication workflow in Heimdall.

Given a OAuth2-Proxy configured with cookie-name: SESSION: When the session cookie is small (<4KB), it is stored under the name SESSION.
When it exceeds the limit, it is split into multiple parts: SESSION_0, SESSION_1, SESSION_N.

Currently, Heimdall does not provide a way to handle this dynamically, leading to failures in both cases:

  • If no cookie splitting occurs (SESSION is used), configurations listing SESSION_0 or SESSION_1 fail because they do not exist.
  • If cookie splitting occurs (SESSION is absent, but SESSION_0, SESSION_1, etc., are present), Heimdall fails to locate the expected cookie.

Example configuration:

- id: auth
  type: generic
  config:
    identity_info_endpoint: http://oauth2-proxy:4180/oauth2/userinfo
    authentication_data_source:
      - cookie: SESSION
    forward_cookies:
      - SESSION
    subject:
      id: "user"

This works when SESSION is available but fails when splitting occurs. If we attempt to list multiple cookies, the opposite problem occurs:

- id: auth
  type: generic
  config:
    identity_info_endpoint: http://oauth2-proxy:4180/oauth2/userinfo
    authentication_data_source:
      - cookie: SESSION
      - cookie: SESSION_0
      - cookie: SESSION_1
    forward_cookies:
      - SESSION
      - SESSION_0
      - SESSION_1
    subject:
      id: "user"

Here, if no splitting happens, SESSION_0 and SESSION_1 do not exist, breaking the workflow.

Describe your idea

A mechanism to handle cookie validation dynamically would be beneficial. Possible approaches include:

  1. OR-based selection

    • Allow authentication using either SESSION or the combination of SESSION_0, SESSION_1, etc.
    • This does not natively handles situations where cookies are split into more than two parts.
  2. Optional cookies

    • Allow defining optional cookies (e.g., SESSION, SESSION_0, SESSION_1) without failing if some are missing.
    • Downside: No validation of expected cookies.
  3. Prefix-based matching

    • Support wildcard or prefix matching (e.g., SESSION* or SESSION_*).
    • Ideally combined with OR logic: SESSION or SESSION_*.
  4. Regex-based selection

    • Allow defining authentication cookie sources with a pattern such as SESSION(?:_[0-9]+)?.
    • More flexible and scalable than listing cookies explicitly.

Considerations:

  • The forward_cookies interface currently supports a static list, making dynamic selection challenging. Some rework would be needed to support this feature.

Are there any workarounds or alternatives?

A partial workaround exists: configuring session-cookie-minimal mode in OAuth2-Proxy (https://github.com/oauth2-proxy/oauth2-proxy/pull/673).

  • This significantly reduces cookie size, avoiding splitting.
  • However, it removes token information, making tokens unavailable to downstream applications.

Version

v0.15.6

Additional Context

Before implementing a complex solution in Heimdall, it is worth considering the discussion in https://github.com/oauth2-proxy/oauth2-proxy/issues/482, which suggest transitioning to server-side session storage solutions, such as Memory, Redis, to manage larger sessions more effectively and eliminate the need for cookie splitting.

aslafy-z avatar Feb 21 '25 15:02 aslafy-z

@aslafy-z: Thank you very much for the FR. I’ve added it to the "Future" backlog for now. This means that once the currently planned release is ready and published, I’ll check with the community to see which FRs are most important, as well as which ones I’d like to prioritize for the next release, and plan accordingly. If this feature is particularly important to you, please let me know, and I’ll try to include it in the release I’m currently working on.

If you can contribute it yourself, that would be great - this is always possible, and the feature will be included in the next release, as I don’t need to plan my time for it. In that case, we should, however, discuss how it should be implemented here or on Discord.

dadrus avatar Feb 21 '25 16:02 dadrus

Frankly speaking, the original intent behind its implementation was to support multiple different sources for authentication data (like e.g. possible with kratos) and handle scenarios involving header/cookie splitting. I have no idea what I was thinking at the implementation time, but it clearly doesn't work as intended. Therefore, I now consider it a bug.

dadrus avatar Feb 26 '25 20:02 dadrus

After reviewing the current implementation and evaluating the alternatives outlined in the description, I believe it’s better to take the necessary time for a well-thought-out design. While I initially called this a bug - since the implementation doesn’t fully align with the original intent - the existing functionality itself isn’t inherently broken. Rather, it lacks support for a specific, yet important, case. Since this isn’t something that can be quickly corrected, and given that workarounds exist, I’ll revisit it when the time is right. Given this perspective, I’ll also relabel this issue back to its original "feature" classification. I initially marked it as a bug after my previous comment, but on reconsideration, I believe it’s more appropriate to treat it as a missing capability rather than a defect.

dadrus avatar Mar 03 '25 12:03 dadrus