Limit OAuth2 resumption to session (#3296)

OAuth2 session resumption was accidentally made a permanent cookie
which led to continuing issues with it causing invalid redirections
after login. Make this a session only cookie.
This commit is contained in:
Firstyear 2024-12-17 11:37:16 +10:00 committed by GitHub
parent 6c3b8500a2
commit 7e9c33ab03
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 28 additions and 28 deletions

View file

@ -268,6 +268,7 @@ pub enum OperationError {
// Web UI
UI0001ChallengeSerialisation,
UI0002InvalidState,
UI0003InvalidOauth2Resume,
// Unixd Things
KU001InitWhileSessionActive,
@ -457,25 +458,26 @@ impl OperationError {
Self::SC0009IndexTypeSyntaxInvalid => Some("A SCIM IndexType contained invalid syntax".into()),
Self::SC0010DateTimeSyntaxInvalid => Some("A SCIM DateTime contained invalid syntax".into()),
Self::SC0011AddressSyntaxInvalid => Some("A SCIM Address contained invalid syntax".into()),
Self::SC0012CertificateSyntaxInvalid => Some("A SCIM Certificate contained invalid binary data".into()),
Self::SC0013CertificateInvalidDer => Some("A SCIM Certificate did not contain valid DER".into()),
Self::SC0014CertificateInvalidDigest => Some("A SCIM Certificate was unable to be digested".into()),
Self::SC0015CredentialTypeSyntaxInvalid => Some("A SCIM CredentialType contained invalid syntax".into()),
Self::SC0016InameSyntaxInvalid => Some("A SCIM Iname string contained invalid syntax".into()),
Self::SC0017Iutf8SyntaxInvalid => Some("A SCIM Iutf8 string contained invalid syntax".into()),
Self::SC0018NsUniqueIdSyntaxInvalid => Some("A SCIM NsUniqueID contained invalid syntax".into()),
Self::SC0019Oauth2ScopeSyntaxInvalid => Some("A SCIM Oauth2 Scope contained invalid syntax".into()),
Self::SC0020Oauth2ScopeMapSyntaxInvalid => Some("A SCIM Oauth2 Scope Map contained invalid syntax".into()),
Self::SC0021Oauth2ScopeMapMissingGroupIdentifier => Some("A SCIM Oauth2 Scope Map was missing a group name or uuid".into()),
Self::SC0022Oauth2ClaimMapSyntaxInvalid => Some("A SCIM Oauth2 Claim Map contained invalid syntax".into()),
Self::SC0023Oauth2ClaimMapMissingGroupIdentifier => Some("A SCIM Claim Map was missing a group name or uuid".into()),
Self::SC0024SshPublicKeySyntaxInvalid => Some("A SCIM Ssh Public Key contained invalid syntax".into()),
Self::SC0025UiHintSyntaxInvalid => Some("A SCIM UiHint contained invalid syntax".into()),
Self::SC0026Utf8SyntaxInvalid => Some("A SCIM Utf8 String Scope Map contained invalid syntax".into()),
Self::SC0011AddressSyntaxInvalid => Some("A SCIM Address contained invalid syntax".into()),
Self::SC0012CertificateSyntaxInvalid => Some("A SCIM Certificate contained invalid binary data".into()),
Self::SC0013CertificateInvalidDer => Some("A SCIM Certificate did not contain valid DER".into()),
Self::SC0014CertificateInvalidDigest => Some("A SCIM Certificate was unable to be digested".into()),
Self::SC0015CredentialTypeSyntaxInvalid => Some("A SCIM CredentialType contained invalid syntax".into()),
Self::SC0016InameSyntaxInvalid => Some("A SCIM Iname string contained invalid syntax".into()),
Self::SC0017Iutf8SyntaxInvalid => Some("A SCIM Iutf8 string contained invalid syntax".into()),
Self::SC0018NsUniqueIdSyntaxInvalid => Some("A SCIM NsUniqueID contained invalid syntax".into()),
Self::SC0019Oauth2ScopeSyntaxInvalid => Some("A SCIM Oauth2 Scope contained invalid syntax".into()),
Self::SC0020Oauth2ScopeMapSyntaxInvalid => Some("A SCIM Oauth2 Scope Map contained invalid syntax".into()),
Self::SC0021Oauth2ScopeMapMissingGroupIdentifier => Some("A SCIM Oauth2 Scope Map was missing a group name or uuid".into()),
Self::SC0022Oauth2ClaimMapSyntaxInvalid => Some("A SCIM Oauth2 Claim Map contained invalid syntax".into()),
Self::SC0023Oauth2ClaimMapMissingGroupIdentifier => Some("A SCIM Claim Map was missing a group name or uuid".into()),
Self::SC0024SshPublicKeySyntaxInvalid => Some("A SCIM Ssh Public Key contained invalid syntax".into()),
Self::SC0025UiHintSyntaxInvalid => Some("A SCIM UiHint contained invalid syntax".into()),
Self::SC0026Utf8SyntaxInvalid => Some("A SCIM Utf8 String Scope Map contained invalid syntax".into()),
Self::UI0001ChallengeSerialisation => Some("The WebAuthn challenge was unable to be serialised.".into()),
Self::UI0002InvalidState => Some("The credential update process returned an invalid state transition.".into()),
Self::UI0003InvalidOauth2Resume => Some("The server attemped to resume OAuth2, but no OAuth2 session is in progress.".into()),
Self::VL0001ValueSshPublicKeyString => None,
Self::VS0001IncomingReplSshPublicKey => None,
Self::VS0002CertificatePublicKeyDigest |

View file

@ -10,11 +10,6 @@ pub fn destroy(jar: CookieJar, ck_id: &str) -> CookieJar {
if let Some(ck) = jar.get(ck_id) {
let mut ck = ck.clone();
ck.make_removal();
/*
if let Some(path) = ck.path().cloned() {
ck.set_path(&path);
}
*/
jar.add(ck)
} else {
jar
@ -37,8 +32,6 @@ pub fn make_unsigned<'a>(
// then webauthn won't work anyway!
token_cookie.set_domain(state.domain.clone());
token_cookie.set_path(path);
// These last forever.
token_cookie.make_permanent();
token_cookie
}
@ -71,8 +64,6 @@ pub fn make_signed<'a, T: Serialize>(
token_cookie.set_http_only(true);
token_cookie.set_path(path);
token_cookie.set_domain(state.domain.clone());
// These last forever, we have our own internal expiration handling.
token_cookie.make_permanent();
Some(token_cookie)
}

View file

@ -926,22 +926,25 @@ async fn view_login_step(
// Important - this can be make unsigned as token_str has it's own
// signatures.
let bearer_cookie = cookies::make_unsigned(
let mut bearer_cookie = cookies::make_unsigned(
&state,
COOKIE_BEARER_TOKEN,
token_str.clone(),
"/",
);
// Important - can be permanent as the token has its own expiration time internally
bearer_cookie.make_permanent();
jar = if session_context.remember_me {
// Important - can be unsigned as username is just for remember
// me and no other purpose.
let username_cookie = cookies::make_unsigned(
let mut username_cookie = cookies::make_unsigned(
&state,
COOKIE_USERNAME,
session_context.username.clone(),
Urls::Login.as_ref(),
);
username_cookie.make_permanent();
jar.add(username_cookie)
} else {
jar

View file

@ -112,7 +112,7 @@ async fn oauth2_auth_req(
return (
jar,
UnrecoverableErrorView {
err_code: OperationError::InvalidState,
err_code: OperationError::UI0003InvalidOauth2Resume,
operation_id: kopid.eventid,
},
)
@ -176,6 +176,10 @@ async fn oauth2_auth_req(
cookies::make_signed(&state, COOKIE_OAUTH2_REQ, &auth_req, Urls::Ui.as_ref())
.map(|mut cookie| {
cookie.set_same_site(SameSite::Strict);
// Expire at the end of the session.
cookie.set_expires(None);
// Could experiment with this to a shorter value, but session should be enough.
cookie.set_max_age(None);
jar.add(cookie)
})
.ok_or(OperationError::InvalidSessionState);