diff --git a/crates/protocols/src/ftps/driver.rs b/crates/protocols/src/ftps/driver.rs index 02ed09fbd..3ca01b348 100644 --- a/crates/protocols/src/ftps/driver.rs +++ b/crates/protocols/src/ftps/driver.rs @@ -233,6 +233,11 @@ where .map_err(|e| Error::new(ErrorKind::PermanentFileNotAvailable, format!("{}: {}", "Invalid path", e)))?; if let Some(key) = key { + // Authorize HeadObject + authorize_operation(session_context, &S3Action::HeadObject, &bucket, Some(&key)) + .await + .map_err(|_| Error::new(ErrorKind::PermanentFileNotAvailable, "Access denied"))?; + match self .storage .head_object( @@ -264,6 +269,11 @@ where } } else { // Directory metadata - use HeadBucket + // Authorize HeadBucket + authorize_operation(session_context, &S3Action::HeadBucket, &bucket, None) + .await + .map_err(|_| Error::new(ErrorKind::PermanentFileNotAvailable, "Access denied"))?; + let bucket_clone = bucket.clone(); match self .storage @@ -434,6 +444,11 @@ where let key = key.ok_or_else(|| Error::new(ErrorKind::PermanentFileNotAvailable, "Cannot get directory"))?; + // Authorize GetObject + authorize_operation(session_context, &S3Action::GetObject, &bucket, Some(&key)) + .await + .map_err(|_| Error::new(ErrorKind::PermanentFileNotAvailable, "Access denied"))?; + match self .storage .get_object( @@ -668,6 +683,11 @@ where .parse_s3_path(&path_str) .map_err(|e| Error::new(ErrorKind::PermanentFileNotAvailable, format!("{}: {}", "Invalid path", e)))?; + // Authorize HeadBucket (CWD probes bucket existence) + authorize_operation(session_context, &S3Action::HeadBucket, &bucket, None) + .await + .map_err(|_| Error::new(ErrorKind::PermanentFileNotAvailable, "Access denied"))?; + // Check if bucket exists match self .storage diff --git a/rustfs/src/admin/handlers/replication.rs b/rustfs/src/admin/handlers/replication.rs index 0d9618ab3..dc357d276 100644 --- a/rustfs/src/admin/handlers/replication.rs +++ b/rustfs/src/admin/handlers/replication.rs @@ -318,11 +318,9 @@ pub struct ListRemoteTargetHandler {} #[async_trait::async_trait] impl Operation for ListRemoteTargetHandler { async fn call(&self, req: S3Request, _params: Params<'_, '_>) -> S3Result> { + validate_replication_admin_request(&req, AdminAction::GetBucketTargetAction).await?; + let queries = extract_query_params(&req.uri); - let Some(_cred) = req.credentials else { - error!("credentials null"); - return Err(s3_error!(InvalidRequest, "get cred failed")); - }; if let Some(bucket) = queries.get("bucket") { if bucket.is_empty() {