Skip to content

Commit 8556676

Browse files
fix(deps): bump publicsuffix to 2.3 to drop vulnerable idna 0.2.3
publicsuffix 1.5 transitively pulls idna 0.2.3, which is affected by CVE-2024-12224 (GHSA-h97m-ww89-6jmq). publicsuffix 2.3 depends on idna 1.0+, which is patched. Closes Dependabot alert #25. The 2.x API replaces List::from_str / parse_domain / Domain::root with str::parse and the Psl trait's suffix() / domain() methods. The new algorithm also applies an implicit wildcard so unlisted TLDs (like "localhost") report themselves as a suffix; filter on Suffix::is_known() to preserve v1 semantics and keep bare "localhost" valid as an rp.id.
1 parent cc1734e commit 8556676

3 files changed

Lines changed: 36 additions & 61 deletions

File tree

Cargo.lock

Lines changed: 12 additions & 53 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libwebauthn/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ base64-url = "3.0.0"
3232
dbus = "0.9.5"
3333
tracing = "0.1.29"
3434
idna = "1.0.3"
35-
publicsuffix = { version = "1.5", default-features = false }
35+
publicsuffix = "2.3"
3636
url = "2.5"
3737
maplit = "1.0.2"
3838
sha2 = "0.10.2"

libwebauthn/src/ops/webauthn/psl.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
1515
use std::path::{Path, PathBuf};
1616

17+
use publicsuffix::{List, Psl};
18+
1719
/// Public Suffix List lookup interface.
1820
///
1921
/// Implementations decide where the PSL data lives (system file, embedded
@@ -42,7 +44,7 @@ pub const SYSTEM_PSL_PATH: &str = "/usr/share/publicsuffix/public_suffix_list.da
4244
/// `PublicSuffixList` implementation backed by a Public Suffix List `.dat`
4345
/// file loaded from disk at construction time.
4446
pub struct DatFilePublicSuffixList {
45-
list: publicsuffix::List,
47+
list: List,
4648
source: PathBuf,
4749
}
4850

@@ -59,8 +61,9 @@ impl DatFilePublicSuffixList {
5961
pub fn from_path(path: impl AsRef<Path>) -> Result<Self, DatFileLoadError> {
6062
let path = path.as_ref();
6163
let data = std::fs::read_to_string(path)?;
62-
let list = publicsuffix::List::from_str(&data)
63-
.map_err(|e| DatFileLoadError::Parse(e.to_string()))?;
64+
let list: List = data
65+
.parse()
66+
.map_err(|e: publicsuffix::Error| DatFileLoadError::Parse(e.to_string()))?;
6467
Ok(Self {
6568
list,
6669
source: path.to_path_buf(),
@@ -74,14 +77,27 @@ impl DatFilePublicSuffixList {
7477
}
7578

7679
impl PublicSuffixList for DatFilePublicSuffixList {
80+
// `is_known()` filter drops `publicsuffix`'s implicit-wildcard match for
81+
// unlisted TLDs (e.g. `localhost`), so bare `localhost` stays a valid rp.id.
7782
fn registrable_domain(&self, host: &str) -> Option<String> {
78-
let domain = self.list.parse_domain(host).ok()?;
79-
domain.root().map(|s| s.to_string())
83+
let suffix = self.list.suffix(host.as_bytes())?;
84+
if !suffix.is_known() {
85+
return None;
86+
}
87+
let domain = self.list.domain(host.as_bytes())?;
88+
std::str::from_utf8(domain.as_bytes())
89+
.ok()
90+
.map(String::from)
8091
}
8192

8293
fn public_suffix(&self, host: &str) -> Option<String> {
83-
let domain = self.list.parse_domain(host).ok()?;
84-
domain.suffix().map(|s| s.to_string())
94+
let suffix = self.list.suffix(host.as_bytes())?;
95+
if !suffix.is_known() {
96+
return None;
97+
}
98+
std::str::from_utf8(suffix.as_bytes())
99+
.ok()
100+
.map(String::from)
85101
}
86102
}
87103

0 commit comments

Comments
 (0)