harbor: Invalidated OIDC session handling
Expected behavior: Docker image push to harbor using CLI secret should fail, and Harbor web UI should handle exiting session as invalid after OIDC session get’s invalidated on OIDC providers side.
- Harbor UI periodically should invoke OIDC providers
check_session_iframeor some other API endpoint to validate if OIDC session hasn’t been invalidated on providers side - similarly how server side core is doing it - Harbor server(core) should thread all OIDC userinfo endpoint error responses as fatal and shouldn’t fallback to “user data from ID token”.
Actual behavior: Docker images can be pushed to harbor, Harbor web UI still allows access project/repositories/etc after OIDC session get’s invalidated on OIDC providers side.
Steps to reproduce the problem:
- Set up harbor with OIDC authentication backed - keycloak
- Enroll/auto onboard harbor user via web front-end (login with oidc provider)
- Generate OIDC user/token specific CLI secret
- Log in into harbor via
docker login -u <oidc username> -p <CLI secret> <harbor url> - Push random image into harbor - as expected OIDC session is still valid
- Open OIDC provider and invalidate all OIDC user sessions associated with harbor client
- Bug number 1 - harbor UI is still accessible in session created in 2nd step
- Bug number 2 - images can be pushed to harbor relying on 4th steps authentication data.
Workaround/mitigation for 8th steps bug Harbor aggressively tracks access tokens validity and if it’s expired then it get’s refreshed via refresh token. I can’t pinpoint exact location in harbors code but if access tokens refresh fails then image push to harbor get’s rejected (as expected) with unauthorized exception. So by relying on this behavior invalidated OIDC session handling bug can be partially mitigated by reducing access tokens validity time to minimum (1 minute) just to force refreshes more often. Yes this puts much more stress OIDC provider but it works.
Versions:
- harbor version: v2.1.1-5f52168e
- docker engine version: 19.03.12
- docker-compose version: 1.26.2
- keycloak version: v10.0.1
Additional context: In log-mix.txt part of core.log mixed in with keycloaks event representation during 8th steps invoke. Location which causes server side issues
PS. If needed I can try to trim down my dockerfiles/keycloak/etc so that this would be easily reproducible, but it will take some time as my keycloak is set up with user federation to active directory and stuff
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 3
- Comments: 15 (3 by maintainers)
I don’t believe that this is entirely true - OIDC providers are/must be state-full (in the same scene as harbors token service) they track authenticated session state - at the end of they day they must know which refresh token maps to witch access token. This in turn gives them option to invalidate existing sessions - just like google and facebook does.
What actually is broken in harbors implementation is compliance with OIDC providers decision during “userInfo” endpoints invoke (it already does get called during each docker pull/push command)
Actual problems resides here https://github.com/goharbor/harbor/blob/v2.1.1/src/common/utils/oidc/helper.go#L250 instead of logging warning and falling back to locally stored token, harbor should reject incoming pull/push operation.
Technically I get that this will introduce runtime dependency on OIDC providers availability - but this can be mitigated by more checks like - if token was issued by OIDC provider less than 5 minutes ago then we trust it’s content (most likely it hasn’t been invalidated) and don’t invoke userinfo at all - this even might be configurable threw UI.
I’m not talking about OIDC providers compromises but about user credential compromises. As far as I get then to mitigate these compromises session invalidation functionality exists. Problem is that when harbor stumbles on this case then it still continues to work using fallback to original token instead of refusing pull/push actions.
You can correct me if I’m wrong - but token expiry isn’t the only case when OIDC session can be thought of as invalid/expired. Sessions can be invalidated by OIDC provider it self as well - lost hardware, compromised credentials, etc. In this case only way how harbor can identify this by by invoking some kind of api on OIDC providers side.
@kautkata This is by design that Harbor use the ID token as the single source of truth the determine if the request is valid. Such that Harbor does not have to communicate with the ID provider before the ID token expires.