aboutsummaryrefslogtreecommitdiff
path: root/src/auth.rs
diff options
context:
space:
mode:
authorBlackDex <[email protected]>2020-12-14 19:58:23 +0100
committerBlackDex <[email protected]>2020-12-14 19:58:23 +0100
commitde86aa671eec9d08ab0e0d4cdd30584606882732 (patch)
treea3f4aba1e2de1a98ac6fef5e96cf919c8428b152 /src/auth.rs
parente38771bbbddcf8ad8135a6e07ad9930341448846 (diff)
downloadvaultwarden-de86aa671eec9d08ab0e0d4cdd30584606882732.tar.gz
vaultwarden-de86aa671eec9d08ab0e0d4cdd30584606882732.zip
Fix Key Rotation during password change
When ticking the 'Also rotate my account's encryption key' box, the key rotated ciphers are posted after the change of password. During the password change the security stamp was reseted which made the posted key's return an invalid auth. This reset is needed to prevent other clients from still being able to read/write. This fixes this by adding a new database column which stores a stamp exception which includes the allowed route and the current security stamp before it gets reseted. When the security stamp check fails it will check if there is a stamp exception and tries to match the route and security stamp. Currently it only allows for one exception. But if needed we could expand it by using a Vec<UserStampException> and change the functions accordingly. fixes #1240
Diffstat (limited to 'src/auth.rs')
-rw-r--r--src/auth.rs32
1 files changed, 22 insertions, 10 deletions
diff --git a/src/auth.rs b/src/auth.rs
index 53a25357..667783cc 100644
--- a/src/auth.rs
+++ b/src/auth.rs
@@ -215,12 +215,10 @@ pub fn generate_admin_claims() -> AdminJWTClaims {
//
// Bearer token authentication
//
-use rocket::{
- request::{FromRequest, Request, Outcome},
-};
+use rocket::request::{FromRequest, Outcome, Request};
use crate::db::{
- models::{Device, User, UserOrgStatus, UserOrgType, UserOrganization, CollectionUser},
+ models::{CollectionUser, Device, User, UserOrgStatus, UserOrgType, UserOrganization, UserStampException},
DbConn,
};
@@ -298,7 +296,25 @@ impl<'a, 'r> FromRequest<'a, 'r> for Headers {
};
if user.security_stamp != claims.sstamp {
- err_handler!("Invalid security stamp")
+ if let Some(stamp_exception) = user
+ .stamp_exception
+ .as_deref()
+ .and_then(|s| serde_json::from_str::<UserStampException>(s).ok())
+ {
+ let current_route = match request.route().and_then(|r| r.name) {
+ Some(name) => name,
+ _ => err_handler!("Error getting current route for stamp exception"),
+ };
+
+ // Check if both match, if not this route is not allowed with the current security stamp.
+ if stamp_exception.route != current_route {
+ err_handler!("Invalid security stamp: Current route and exception route do not match")
+ } else if stamp_exception.security_stamp != claims.sstamp {
+ err_handler!("Invalid security stamp for matched stamp exception")
+ }
+ } else {
+ err_handler!("Invalid security stamp")
+ }
}
Outcome::Success(Headers { host, device, user })
@@ -423,10 +439,6 @@ impl Into<Headers> for AdminHeaders {
}
}
-
-
-
-
// col_id is usually the forth param ("/organizations/<org_id>/collections/<col_id>")
// But there cloud be cases where it is located in a query value.
// First check the param, if this is not a valid uuid, we will try the query value.
@@ -478,7 +490,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for ManagerHeaders {
None => err_handler!("The current user isn't a manager for this collection"),
}
}
- },
+ }
_ => err_handler!("Error getting the collection id"),
}