PDF export also drops search: and search-ms: links

Windows Search's search: and search-ms: links can name a folder on
another machine through crumb=location:, and opening one connects to
that host and sends the user's NTLM credentials. They are now left out
of the PDF like the other network-share links, and the test covers both.
This commit is contained in:
oracola91
2026-10-24 13:27:00 +03:00
parent 8c4907a626
commit afb52aeef3
2 changed files with 5 additions and 2 deletions
+3 -2
View File
@@ -695,7 +695,8 @@ fn to_path(bp: &kurbo::BezPath) -> Option<krilla::geom::Path> {
/// Can a hyperlink from a (possibly untrusted) deck become a PDF link? Scripts (`javascript:`,
/// `vbscript:`), `data:` and paths to another machine (`\\host\share`, `//host/share`,
/// `file://host/...`, `smb://host/...`) cannot: opening one connects to that host, which on Windows
/// `file://host/...`, `smb://host/...`, and Windows Search's `search:` and `search-ms:`, whose
/// `crumb=location:` can name one) cannot: opening one connects to that host, which on Windows
/// sends the user's NTLM credentials. Web, mail, local `file:` and relative links can. Read the way
/// a browser reads a URL: control characters dropped, leading spaces trimmed, any case.
fn exportable_url(url: &str) -> bool {
@@ -706,7 +707,7 @@ fn exportable_url(url: &str) -> bool {
}
let Some((scheme, rest)) = u.split_once(':') else { return true };
match scheme.to_ascii_lowercase().as_str() {
"javascript" | "vbscript" | "data" | "smb" => false,
"javascript" | "vbscript" | "data" | "smb" | "search" | "search-ms" => false,
"file" => match rest.strip_prefix("//") {
// `file:///C:/...` and `file://localhost/...` are local; `file://host/...` and `file:////host/...` are not.
Some(p) => {
+2
View File
@@ -150,6 +150,8 @@ fn unsafe_url_links_are_not_exported() {
"file://attacker.example/share/x",
"file:////attacker.example/share/x",
"smb://attacker.example/share/x",
"search-ms:query=x&crumb=location:\\\\attacker.example\\share",
"search:query=x&crumb=location:\\\\attacker.example\\share",
];
let mut p = deck(1);
let slide = Arc::make_mut(&mut p.slides[0]);