Skip to content

Commit e2a1f19

Browse files
fix password reset grpc sending unparsed user agent (#1546)
Co-authored-by: Filip Ślęzak <[email protected]>
1 parent 1d7b18c commit e2a1f19

File tree

6 files changed

+22
-18
lines changed

6 files changed

+22
-18
lines changed

crates/defguard_core/src/grpc/password_reset.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::{
1818
mail::{send_password_reset_email, send_password_reset_success_email},
1919
user::check_password_strength,
2020
},
21+
headers::get_device_info,
2122
mail::Mail,
2223
server_config,
2324
};
@@ -99,13 +100,14 @@ impl PasswordResetServer {
99100
debug!("Starting password reset request");
100101

101102
let ip_address;
102-
let user_agent;
103+
let device_info;
103104
if let Some(ref info) = req_device_info {
104105
ip_address = info.ip_address.clone();
105-
user_agent = info.user_agent.clone().unwrap_or_default();
106+
let agent = info.user_agent.clone().unwrap_or_default();
107+
device_info = get_device_info(&agent);
106108
} else {
107109
ip_address = String::new();
108-
user_agent = String::new();
110+
device_info = String::new();
109111
}
110112

111113
let email = request.email;
@@ -152,14 +154,13 @@ impl PasswordResetServer {
152154
error!("Failed to commit transaction");
153155
Status::internal("unexpected error")
154156
})?;
155-
156157
send_password_reset_email(
157158
&user,
158159
&self.mail_tx,
159160
config.enrollment_url.clone(),
160161
&enrollment.id,
161162
Some(&ip_address),
162-
Some(&user_agent),
163+
Some(&device_info),
163164
)?;
164165

165166
info!(
@@ -255,13 +256,14 @@ impl PasswordResetServer {
255256
let enrollment = self.validate_session(request.token.as_ref()).await?;
256257

257258
let ip_address;
258-
let user_agent;
259+
let device_info;
259260
if let Some(ref info) = req_device_info {
260261
ip_address = info.ip_address.clone();
261-
user_agent = info.user_agent.clone().unwrap_or_default();
262+
let agent = info.user_agent.clone().unwrap_or_default();
263+
device_info = get_device_info(&agent);
262264
} else {
263265
ip_address = String::new();
264-
user_agent = String::new();
266+
device_info = String::new();
265267
}
266268

267269
if let Err(err) = check_password_strength(&request.password) {
@@ -302,7 +304,7 @@ impl PasswordResetServer {
302304
&user,
303305
&self.mail_tx,
304306
Some(&ip_address),
305-
Some(&user_agent),
307+
Some(&device_info),
306308
)?;
307309

308310
// Prepare event context and push the event

crates/defguard_core/src/grpc/utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ pub(crate) fn parse_client_info(info: &Option<DeviceInfo>) -> Result<(IpAddr, St
216216
msg
217217
})?;
218218
let user_agent = info.user_agent.clone().unwrap_or_else(String::new);
219+
let escaped_agent = tera::escape_html(&user_agent);
219220

220-
Ok((ip, user_agent))
221+
Ok((ip, escaped_agent))
221222
}

crates/defguard_core/src/handlers/mail.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ static EMAIL_MFA_CODE_EMAIL_SUBJECT: &str = "Your Multi-Factor Authentication Co
3939
static GATEWAY_DISCONNECTED: &str = "Defguard: Gateway disconnected";
4040
static GATEWAY_RECONNECTED: &str = "Defguard: Gateway reconnected";
4141

42-
pub static EMAIL_PASSOWRD_RESET_START_SUBJECT: &str = "Defguard: Password reset";
43-
pub static EMAIL_PASSOWRD_RESET_SUCCESS_SUBJECT: &str = "Defguard: Password reset success";
42+
pub static EMAIL_PASSWORD_RESET_START_SUBJECT: &str = "Defguard: Password reset";
43+
pub static EMAIL_PASSWORD_RESET_SUCCESS_SUBJECT: &str = "Defguard: Password reset success";
4444

4545
#[derive(Clone, Deserialize)]
4646
pub struct TestMail {
@@ -461,7 +461,7 @@ pub fn send_password_reset_email(
461461

462462
let mail = Mail {
463463
to: user.email.clone(),
464-
subject: EMAIL_PASSOWRD_RESET_START_SUBJECT.into(),
464+
subject: EMAIL_PASSWORD_RESET_START_SUBJECT.into(),
465465
content: templates::email_password_reset_mail(service_url, token, ip_address, device_info)?,
466466
attachments: Vec::new(),
467467
result_tx: None,
@@ -491,7 +491,7 @@ pub fn send_password_reset_success_email(
491491

492492
let mail = Mail {
493493
to: user.email.clone(),
494-
subject: EMAIL_PASSOWRD_RESET_SUCCESS_SUBJECT.into(),
494+
subject: EMAIL_PASSWORD_RESET_SUCCESS_SUBJECT.into(),
495495
content: templates::email_password_reset_success_mail(ip_address, device_info)?,
496496
attachments: Vec::new(),
497497
result_tx: None,

crates/defguard_core/src/handlers/user.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use serde_json::json;
88

99
use super::{
1010
AddUserData, ApiResponse, ApiResult, PasswordChange, PasswordChangeSelf,
11-
StartEnrollmentRequest, Username, mail::EMAIL_PASSOWRD_RESET_START_SUBJECT,
11+
StartEnrollmentRequest, Username, mail::EMAIL_PASSWORD_RESET_START_SUBJECT,
1212
user_for_admin_or_self,
1313
};
1414
use crate::{
@@ -1086,7 +1086,7 @@ pub async fn reset_password(
10861086

10871087
let mail = Mail {
10881088
to: user.email.clone(),
1089-
subject: EMAIL_PASSOWRD_RESET_START_SUBJECT.into(),
1089+
subject: EMAIL_PASSWORD_RESET_START_SUBJECT.into(),
10901090
content: templates::email_password_reset_mail(
10911091
config.enrollment_url.clone(),
10921092
enrollment.id.clone().as_str(),

crates/defguard_core/src/headers.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ pub(crate) static USER_AGENT_PARSER: LazyLock<UserAgentParser> = LazyLock::new(|
2424

2525
#[must_use]
2626
pub(crate) fn get_device_info(user_agent: &str) -> String {
27-
let client = USER_AGENT_PARSER.parse(user_agent);
27+
let escaped = tera::escape_html(user_agent);
28+
let client = USER_AGENT_PARSER.parse(&escaped);
2829
get_user_agent_device(&client)
2930
}
3031

crates/defguard_core/templates/base.tera

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@
261261
{% endif %}
262262
{% if device_type %}
263263
<p style="margin: auto;">
264-
<span>Device type:</span> {{ device_type | safe }}
264+
<span>Device type:</span> {{ device_type }}
265265
</p>
266266
{% endif %}
267267
</div>

0 commit comments

Comments
 (0)