Skip to content

Commit e33c19d

Browse files
committed
Security and performance hardening from rust-engineer audit
Stop echoing magic link code in response, reject short codes early, use synchronous=FULL for crash-safe vault durability, fix clippy lints.
1 parent 4f49c84 commit e33c19d

File tree

4 files changed

+10
-5
lines changed

4 files changed

+10
-5
lines changed

src/credentials.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ impl std::fmt::Debug for Credentials {
4141
}
4242

4343
impl Credentials {
44+
#[allow(clippy::too_many_arguments)]
4445
pub fn new(
4546
domain: String,
4647
signing_key: &SigningKey,

src/crypto/signing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn decode_public_key(encoded: &str) -> Result<VerifyingKey> {
3939

4040
pub fn encode_private_key(signing_key: &SigningKey) -> String {
4141
let key_bytes = Zeroizing::new(signing_key.to_bytes());
42-
BASE64.encode(&*key_bytes)
42+
BASE64.encode(*key_bytes)
4343
}
4444

4545
pub fn decode_private_key(encoded: &str) -> Result<SigningKey> {

src/db.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub fn open() -> Result<Connection> {
2323

2424
// WAL mode: fast reads, lets multiple processes access the file
2525
conn.pragma_update(None, "journal_mode", "WAL")?;
26-
conn.pragma_update(None, "synchronous", "NORMAL")?;
26+
conn.pragma_update(None, "synchronous", "FULL")?;
2727
conn.pragma_update(None, "cache_size", "-2000")?;
2828

2929
// CREATE TABLE IF NOT EXISTS is idempotent — safe to run every time

src/server.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ struct DepositResponse {
7070
#[derive(Serialize)]
7171
struct MagicLinkResponse {
7272
status: &'static str,
73-
code: String,
7473
}
7574

7675
/// Max deposit body size: 1 MB
@@ -299,6 +298,11 @@ async fn handle_magic_link(
299298
return StatusCode::TOO_MANY_REQUESTS.into_response();
300299
}
301300

301+
// Reject obviously short codes before touching the DB (host() enforces >= 20 chars)
302+
if code.len() < 20 {
303+
return StatusCode::NOT_FOUND.into_response();
304+
}
305+
302306
let state_clone = state.clone();
303307
let code_clone = code;
304308
let result = tokio::task::spawn_blocking(move || {
@@ -308,8 +312,8 @@ async fn handle_magic_link(
308312
}).await;
309313

310314
match result {
311-
Ok(Ok(Some(verified_code))) => {
312-
let resp = MagicLinkResponse { status: "verified", code: verified_code };
315+
Ok(Ok(Some(_))) => {
316+
let resp = MagicLinkResponse { status: "verified" };
313317
match serde_json::to_string(&resp) {
314318
Ok(json) => (StatusCode::OK, [(header::CONTENT_TYPE, "application/json")], json).into_response(),
315319
Err(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),

0 commit comments

Comments
 (0)