temporalio / ui

Temporal UI
https://docs.temporal.io/web-ui
MIT License
187 stars 69 forks source link

SSO login failing with "State cookie is not set in request" error #1269

Open zboralski opened 1 year ago

zboralski commented 1 year ago

Describe the bug

When using SSO to log in, the first attempt results in a "State cookie is not set in request" error.

The user needs to go back and click SSO again to log in successfully.

Additionally, the access token and ID token are being set as cookies, which is a potential security issue.

Request 1 fails

GET /auth/sso/callback?code=REDACTED&state=yo0pO_swUqICNNhRHyEbUw HTTP/1.1
Host: 127.0.0.1:8233
sec-ch-ua: "Chromium";v="111", "Not(A:Brand";v="8"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.111 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.9
Connection: close

Response

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=UTF-8
Set-Cookie: _csrf=BQ2XjK5TxgV8sqQHFZ98nsfYbdKlDd9N; Path=/; Expires=Wed, 05 Apr 2023 04:34:42 GMT; Secure; SameSite=Strict
Vary: Origin
Vary: Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
Date: Tue, 04 Apr 2023 04:34:42 GMT
Content-Length: 49
Connection: close

{"message":"State cookie is not set in request"}

Request 2 succeeds

GET /auth/sso/callback?code=EwioyEx86jMJbRfIctksT0UMlAF3N5XS&state=lik-LgmLn6t-EDovjvsVzQ HTTP/1.1
Host: 127.0.0.1:8233
sec-ch-ua: "Chromium";v="111", "Not(A:Brand";v="8"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.111 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.9
Cookie: state=lik-LgmLn6t-EDovjvsVzQ; nonce=eyJub25jZSI6IlVjekhSNjRTVUJyM0VXNUotbG91VVEiLCJyZXR1cm5fdXJsIjoiaHR0cDovLzEyNy4wLjAuMTo4MjMzLyJ9
Connection: close

Response 2

HTTP/1.1 303 See Other
Location: http://127.0.0.1:8233/
Set-Cookie: _csrf=xZfyQoeTRxrRw8KrRMFee3pALgaIeZEJ; Path=/; Expires=Wed, 05 Apr 2023 04:36:23 GMT; Secure; SameSite=Strict
Set-Cookie: user0=<REDACTED>; Path=/; Max-Age=60; SameSite=Strict
Vary: Origin
Vary: Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
Date: Tue, 04 Apr 2023 04:36:23 GMT
Content-Length: 0
Connection: close

Decoded Cookie

{"AccessToken":"","IDToken":"","Name":"","Email":"","Picture":""}

To Reproduce Steps to reproduce the behavior:

  1. Go to 'http://localhost:8233'
  2. Click on 'Continue to SSO'
  3. See error 'State cookie is not set in request'
  4. Go to 'http://localhost:8233'
  5. Click on 'Continue to SSO'

Expected behavior SSO should log in the user on the first attempt and not set tokens as cookies.

Screenshots

Screenshot 2023-04-04 at 05 35 07

Desktop (please complete the following information):

Additional context

According to the OpenID Connect (OIDC) Core standard: "The state parameter is used to link the authentication request with the response." Therefore, the OAuth flow should grab the state param from the GET parameter for state, rather than relying on a cookie. Additionally, setting access and ID tokens as cookies is a potential security issue, as cookies can be stolen by malicious actors. I suggest using a more secure method for handling tokens, such as session storage or local storage.

feedmeapples commented 1 year ago

for more context this happens with Vault as the OIDC provider

jnunes-tc commented 1 year ago

Any updates on this? Do you have another self-hosted provider to recommend? All of our infrastructure use Vault but if we can't use we can think of another provider for now.

feedmeapples commented 1 year ago

hey @jnunes-tc

Therefore, the OAuth flow should grab the state param from the GET parameter for state

We do read it from GET search params and then compare against the cookie state https://github.com/temporalio/ui/blob/ce57e5792a89ac1c1f7b016c9f3c8874b99a9e07/server/server/auth/oidc.go#L66

All of our infrastructure use Vault but if we can't use we can think of another provider for now.

Keycloak is a pretty popular self hosted OIDC provider. I only started looking into Vault's provider and haven't addressed, unlikely that have enough capacity. If you still want to use Vault would appreciate a contribution if you find what causes this behavior 🙏