Skip to content

Commit f3616f2

Browse files
Add logging of hashed authorization information (#12255)
... for cross-checking usage of compromised keys. Specifically, adds a `custom_metadata.auth_type` value, specifying the authentication type used for actions. Additionally, adds `http.request.headers.hashed_authorization` and `http.request.headers.hashed_cookie` for logging SHA256 hashed copies of the authorization and/or cookie headers used in the request.
1 parent a4c6715 commit f3616f2

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

src/auth.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,19 @@ async fn authenticate(parts: &Parts, conn: &mut AsyncPgConnection) -> AppResult<
288288

289289
match authenticate_via_cookie(parts, conn).await {
290290
Ok(None) => {}
291-
Ok(Some(auth)) => return Ok(Authentication::Cookie(auth)),
291+
Ok(Some(auth)) => {
292+
parts.request_log().add("auth_type", "cookie");
293+
return Ok(Authentication::Cookie(auth));
294+
}
292295
Err(err) => return Err(err),
293296
}
294297

295298
match authenticate_via_token(parts, conn).await {
296299
Ok(None) => {}
297-
Ok(Some(auth)) => return Ok(Authentication::Token(auth)),
300+
Ok(Some(auth)) => {
301+
parts.request_log().add("auth_type", "token");
302+
return Ok(Authentication::Token(auth));
303+
}
298304
Err(err) => return Err(err),
299305
}
300306

src/controllers/krate/publish.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult<Json<Go
172172
.transpose()?;
173173

174174
let auth = if let Some(trustpub_token) = trustpub_token {
175+
request_log.add("auth_type", "trustpub");
176+
175177
let Some(existing_crate) = &existing_crate else {
176178
let error = forbidden(
177179
"Trusted Publishing tokens do not support creating new crates. Publish the crate manually, first",

src/middleware/log_request.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ use axum::response::IntoResponse;
1212
use axum_extra::TypedHeader;
1313
use axum_extra::headers::UserAgent;
1414
use derive_more::Deref;
15-
use http::{Method, Uri};
15+
use http::{Method, Uri, header};
1616
use parking_lot::Mutex;
17+
use sha2::{Digest, Sha256};
1718
use std::borrow::Cow;
1819
use std::collections::HashMap;
1920
use std::fmt::Display;
@@ -48,6 +49,16 @@ pub async fn log_requests(
4849
let custom_metadata = RequestLog::default();
4950
req.extensions_mut().insert(custom_metadata.clone());
5051

52+
// Log all authorization headers via hashed mask
53+
let hashed_auth_header = req
54+
.headers()
55+
.get(header::AUTHORIZATION)
56+
.map(|header| hex::encode(Sha256::digest(header.as_bytes())));
57+
let hashed_cookie_header = req
58+
.headers()
59+
.get(header::COOKIE)
60+
.map(|header| hex::encode(Sha256::digest(header.as_bytes())));
61+
5162
let response = next.run(req).await;
5263

5364
let duration = start_instant.elapsed();
@@ -83,6 +94,8 @@ pub async fn log_requests(
8394
http.matched_path = %matched_path,
8495
http.request_id = %request_metadata.request_id.as_ref().map(|h| h.as_str()).unwrap_or_default(),
8596
http.useragent = %request_metadata.user_agent.as_ref().map(|h| h.as_str()).unwrap_or_default(),
97+
http.request.headers.hashed_authorization = hashed_auth_header.unwrap_or_default(),
98+
http.request.headers.hashed_cookie = hashed_cookie_header.unwrap_or_default(),
8699
http.status_code = status.as_u16(),
87100
cause = response.extensions().get::<CauseField>().map(|e| e.0.as_str()).unwrap_or_default(),
88101
error.message = response.extensions().get::<ErrorField>().map(|e| e.0.as_str()).unwrap_or_default(),

0 commit comments

Comments
 (0)