Skip to content
This repository has been archived by the owner on Dec 7, 2020. It is now read-only.

Large kc_access cookies appear to be improperly decoded prior to parsing #409

Closed
jcrowthe opened this issue Aug 15, 2018 · 10 comments
Closed

Comments

@jcrowthe
Copy link

I am looking to utilize keycloak-proxy with Azure AD using OIDC. It appears to be functional, with the expected JWT token being return to the keycloak-proxy, but I receive the following errors in redirect loop:

...
error	keycloak-proxy/middleware.go:108	no session found in request, redirecting for authorization	{"error": "malformed JWS, only 2 segments"}
debug	keycloak-proxy/handlers.go:81	incoming authorization request from client address	{"access_type": "", "auth_url": "<my-url>", "client_ip": "10.1.7.66:38966"}
warn	keycloak-proxy/handlers.go:140	unable to parse the access token, using id token only	{"error": "malformed JWS, only 1 segments"}
info	keycloak-proxy/handlers.go:160	issuing access token for user	{"email": "", "expires": "2018-08-15T20:34:58Z", "duration": "59m59.838099673s"}
error	keycloak-proxy/middleware.go:108	no session found in request, redirecting for authorization	{"error": "malformed JWS, only 2 segments"}
debug	keycloak-proxy/handlers.go:81	incoming authorization request from client address	{"access_type": "", "auth_url": "<my-url>", "client_ip": "10.1.7.66:38966"}
warn	keycloak-proxy/handlers.go:140	unable to parse the access token, using id token only	{"error": "malformed JWS, only 1 segments"}
info	keycloak-proxy/handlers.go:160	issuing access token for user	{"email": "", "expires": "2018-08-15T20:34:58Z", "duration": "59m59.037853008s"}
error	keycloak-proxy/middleware.go:108	no session found in request, redirecting for authorization	{"error": "malformed JWS, only 2 segments"}
debug	keycloak-proxy/handlers.go:81	incoming authorization request from client address	{"access_type": "", "auth_url": "<my-url>", "client_ip": "10.1.7.66:38966"}
warn	keycloak-proxy/handlers.go:140	unable to parse the access token, using id token only	{"error": "malformed JWS, only 1 segments"}
...

In taking a packet capture of keycloak-proxy (SSL offloaded previously), I receive the following (JWT obscured):

HTTP/1.1 307 Temporary Redirect
Content-Type: text/html; charset=utf-8
Location: /
Set-Cookie: kc-access=eyJ0eXAi...; Path=/; Domain=dashboard.k8s-alpha.ethos.adobe.net; HttpOnly
Set-Cookie: kc-access-1=...HQQP6zvw; Path=/; Domain=dashboard.k8s-alpha.ethos.adobe.net; HttpOnly
Date: Wed, 15 Aug 2018 20:25:03 GMT
Content-Length: 37

<a href="/">Temporary Redirect</a>.

I can extract and concatenate the two kc-access values to produce a valid JWT token, including a vast number of groups (all of which are very long GUID's).

The malformed JWS, only [1|2] segments appears to be originating from here. I believe there is some error in the concatenating code where the token is not being concatenated properly prior to being decoded with coreos/go-oidc.

Any help here would be greatly appreciated!

@jangaraj
Copy link
Contributor

My PR: https://github.com/gambol99/keycloak-proxy/pull/279/files
Current code for concatenating: https://github.com/gambol99/keycloak-proxy/blob/master/session.go#L103-L126
Playground to verify concatenating: https://play.golang.org/p/AG6nRYJxLV4

I'm not sure what is wrong here.

@jcrowthe
Copy link
Author

My hypothesis could very well be incorrect, and I'm happy to accept that! Do you have another idea why malformed JWS errors would be produced, when the JWT token is confirmed valid?

@jcrowthe
Copy link
Author

Config currently used:

        args:
          - --listen=0.0.0.0:3000
          - --discovery-url=https://sts.windows.net/<my-tenant-id>/
          - --client-id=<my-client-id>
          - --client-secret=<my-secret>
          - --redirection-url=https://dashboard.example.com/
          # - --enable-refresh-tokens=true
          # - --encryption-key=asdfasdfasdfasdfasdfasdfasdfasdf
          - --upstream-url=http://kubernetes-dashboard.kube-system.svc.cluster.local
          - --resources=uri=/*
          - --secure-cookie=false
          - --verbose
          - --enable-logging=true
          - --enable-json-logging=true

@jangaraj
Copy link
Contributor

Any middle box between browser and keycloak-proxy? I see k8s, so probably nginx is there and nginx doesn't have a good default configuration for large request headers (and you are sending quite huge cookies there). Try to check your middleboxes logs. Maybe some middle box is dropping/truncating cookies. Are the cookies stored correctly in the browser?

@jcrowthe
Copy link
Author

I believe I've found the error. I just changed the k8s services to be of type LoadBalancer and hit the public IP address, this way the only middleman is Azure LB (which is only a layer 4 LB, so no limits on header/cookie sizes). I receive the same error.

However, in checking chrome devtools, I receive the following warning:

Set-Cookie header is ignored in response from url: http:///oauth/callback?code=AQAB...2diAA&state=Lw%3d%3d&session_state=b7f73fdd-b64b-4120-88da-69ab04557ae1. Cookie length should be less than or equal to 4096 characters.

Looks like the cookie is still too long.

@jcrowthe
Copy link
Author

jcrowthe commented Aug 15, 2018

In piping the value of just the kc-access=...; to wc -c, we get 4091 bytes, however I'm reading that the entire cookie, including the path, expiration , and domain are also part of the 4096 byte limit per cookie. When including this information, I get 4174 bytes.

@jangaraj Would you be able to produce a test docker build that reduces the 4089 limit down to about 4000?

@jangaraj
Copy link
Contributor

Yes, that's a problem. I've used information from http://browsercookielimits.squawky.net/.
Minimum of all Max Size Per Cookie is 4093 - 4 bytes for name suffix "-xxx" = 4089, which is used in the source code: https://github.com/gambol99/keycloak-proxy/blob/master/cookies.go#L47-L65.
You are right, my math is wrong in this case. You may try to use the 4000 limit.

@jcrowthe
Copy link
Author

Confirmed. Thanks to a well-made makefile, I was able to build, push an image to docker hub and pull it on a k8s cluster to test. I now have made it out of the redirect loop, and am forwarded on to the k8s dashboard. See #410 for a quick PR to address this.

@jangaraj
Copy link
Contributor

jangaraj commented Aug 18, 2018

Not tested version - WIP: master...jangaraj:master

@jcrowthe Could you test it, please?

Relevant settings of keycloak-proxy:

enable-session-cookies
cookie-domain
cookie-access-name
cookie-refresh-name
secure-cookie
http-only-cookie

For the record, Set-Cookie: examples:

<CookieAccessName>-xxx=<access-token>; Path=/; Domain=<domain>; Expires=Mon, 02 Jan 2006 03:04:05 MST; Secure
<CookieAccessName>-xxx=<access-token>; Path=/; Domain=<domain>; HttpOnly; Secure

Max cookie size - https://www.ietf.org/rfc/rfc2109.txt:

at least 4096 bytes per cookie (as measured by the size of the characters that comprise the cookie non-terminal in the syntax description of the Set-Cookie header)

Constant 4093 has been used, because of Safari.

@abstractj
Copy link

@jcrowthe it seems like your issue was addressed in @jangaraj's PR. The repository keycloak-proxy was moved to Keycloak organization and renamed to keycloak-gatekeeper. If you still think this issue is valid, please read https://www.keycloak.org/community.html and report your bug/feature request to https://issues.jboss.org/browse/KEYCLOAK.

jeffreyalles pushed a commit to jeffreyalles/keycloak-proxy that referenced this issue May 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants