Skip to content

Commit 72389b0

Browse files
authored
Merge pull request from GHSA-6mv3-wm7j-h4w5
* fix(core): use `require_literal_separator` when matching paths * document the need for `require_literal_separator` * use `require_literal_leading_dot`
1 parent 4f2fd4d commit 72389b0

File tree

2 files changed

+103
-24
lines changed

2 files changed

+103
-24
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": "patch"
3+
---
4+
5+
Fix the filesystem scope allowing sub-directories of the directory picked by the dialog when `recursive` option was `false`.

core/tauri/src/scope/fs.rs

+98-24
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ impl Scope {
141141
/// Extend the allowed patterns with the given directory.
142142
///
143143
/// After this function has been called, the frontend will be able to use the Tauri API to read
144-
/// the directory and all of its files and subdirectories.
144+
/// the directory and all of its files. If `recursive` is `true`, subdirectories will be accessible too.
145145
pub fn allow_directory<P: AsRef<Path>>(&self, path: P, recursive: bool) -> crate::Result<()> {
146146
let path = path.as_ref();
147147
{
@@ -216,13 +216,22 @@ impl Scope {
216216

217217
if let Ok(path) = path {
218218
let path: PathBuf = path.components().collect();
219+
let options = glob::MatchOptions {
220+
// this is needed so `/dir/*` doesn't match files within subdirectories such as `/dir/subdir/file.txt`
221+
// see: https://github.com/tauri-apps/tauri/security/advisories/GHSA-6mv3-wm7j-h4w5
222+
require_literal_separator: true,
223+
// dotfiles are not supposed to be exposed by default
224+
#[cfg(unix)]
225+
require_literal_leading_dot: true,
226+
..Default::default()
227+
};
219228

220229
let forbidden = self
221230
.forbidden_patterns
222231
.lock()
223232
.unwrap()
224233
.iter()
225-
.any(|p| p.matches_path(&path));
234+
.any(|p| p.matches_path_with(&path, options));
226235

227236
if forbidden {
228237
false
@@ -232,7 +241,7 @@ impl Scope {
232241
.lock()
233242
.unwrap()
234243
.iter()
235-
.any(|p| p.matches_path(&path));
244+
.any(|p| p.matches_path_with(&path, options));
236245
allowed
237246
}
238247
} else {
@@ -269,32 +278,97 @@ mod tests {
269278
#[test]
270279
fn path_is_escaped() {
271280
let scope = new_scope();
272-
scope.allow_directory("/home/tauri/**", false).unwrap();
273-
assert!(scope.is_allowed("/home/tauri/**"));
274-
assert!(scope.is_allowed("/home/tauri/**/file"));
275-
assert!(!scope.is_allowed("/home/tauri/anyfile"));
281+
#[cfg(unix)]
282+
{
283+
scope.allow_directory("/home/tauri/**", false).unwrap();
284+
assert!(scope.is_allowed("/home/tauri/**"));
285+
assert!(scope.is_allowed("/home/tauri/**/file"));
286+
assert!(!scope.is_allowed("/home/tauri/anyfile"));
287+
}
288+
#[cfg(windows)]
289+
{
290+
scope.allow_directory("C:\\home\\tauri\\**", false).unwrap();
291+
assert!(scope.is_allowed("C:\\home\\tauri\\**"));
292+
assert!(scope.is_allowed("C:\\home\\tauri\\**\\file"));
293+
assert!(!scope.is_allowed("C:\\home\\tauri\\anyfile"));
294+
}
276295

277296
let scope = new_scope();
278-
scope.allow_file("/home/tauri/**").unwrap();
279-
assert!(scope.is_allowed("/home/tauri/**"));
280-
assert!(!scope.is_allowed("/home/tauri/**/file"));
281-
assert!(!scope.is_allowed("/home/tauri/anyfile"));
297+
#[cfg(unix)]
298+
{
299+
scope.allow_file("/home/tauri/**").unwrap();
300+
assert!(scope.is_allowed("/home/tauri/**"));
301+
assert!(!scope.is_allowed("/home/tauri/**/file"));
302+
assert!(!scope.is_allowed("/home/tauri/anyfile"));
303+
}
304+
#[cfg(windows)]
305+
{
306+
scope.allow_file("C:\\home\\tauri\\**").unwrap();
307+
assert!(scope.is_allowed("C:\\home\\tauri\\**"));
308+
assert!(!scope.is_allowed("C:\\home\\tauri\\**\\file"));
309+
assert!(!scope.is_allowed("C:\\home\\tauri\\anyfile"));
310+
}
311+
312+
let scope = new_scope();
313+
#[cfg(unix)]
314+
{
315+
scope.allow_directory("/home/tauri", true).unwrap();
316+
scope.forbid_directory("/home/tauri/**", false).unwrap();
317+
assert!(!scope.is_allowed("/home/tauri/**"));
318+
assert!(!scope.is_allowed("/home/tauri/**/file"));
319+
assert!(scope.is_allowed("/home/tauri/**/inner/file"));
320+
assert!(scope.is_allowed("/home/tauri/inner/folder/anyfile"));
321+
assert!(scope.is_allowed("/home/tauri/anyfile"));
322+
}
323+
#[cfg(windows)]
324+
{
325+
scope.allow_directory("C:\\home\\tauri", true).unwrap();
326+
scope
327+
.forbid_directory("C:\\home\\tauri\\**", false)
328+
.unwrap();
329+
assert!(!scope.is_allowed("C:\\home\\tauri\\**"));
330+
assert!(!scope.is_allowed("C:\\home\\tauri\\**\\file"));
331+
assert!(scope.is_allowed("C:\\home\\tauri\\**\\inner\\file"));
332+
assert!(scope.is_allowed("C:\\home\\tauri\\inner\\folder\\anyfile"));
333+
assert!(scope.is_allowed("C:\\home\\tauri\\anyfile"));
334+
}
282335

283336
let scope = new_scope();
284-
scope.allow_directory("/home/tauri", true).unwrap();
285-
scope.forbid_directory("/home/tauri/**", false).unwrap();
286-
assert!(!scope.is_allowed("/home/tauri/**"));
287-
assert!(!scope.is_allowed("/home/tauri/**/file"));
288-
assert!(!scope.is_allowed("/home/tauri/**/inner/file"));
289-
assert!(scope.is_allowed("/home/tauri/inner/folder/anyfile"));
290-
assert!(scope.is_allowed("/home/tauri/anyfile"));
337+
#[cfg(unix)]
338+
{
339+
scope.allow_directory("/home/tauri", true).unwrap();
340+
scope.forbid_file("/home/tauri/**").unwrap();
341+
assert!(!scope.is_allowed("/home/tauri/**"));
342+
assert!(scope.is_allowed("/home/tauri/**/file"));
343+
assert!(scope.is_allowed("/home/tauri/**/inner/file"));
344+
assert!(scope.is_allowed("/home/tauri/anyfile"));
345+
}
346+
#[cfg(windows)]
347+
{
348+
scope.allow_directory("C:\\home\\tauri", true).unwrap();
349+
scope.forbid_file("C:\\home\\tauri\\**").unwrap();
350+
assert!(!scope.is_allowed("C:\\home\\tauri\\**"));
351+
assert!(scope.is_allowed("C:\\home\\tauri\\**\\file"));
352+
assert!(scope.is_allowed("C:\\home\\tauri\\**\\inner\\file"));
353+
assert!(scope.is_allowed("C:\\home\\tauri\\anyfile"));
354+
}
291355

292356
let scope = new_scope();
293-
scope.allow_directory("/home/tauri", true).unwrap();
294-
scope.forbid_file("/home/tauri/**").unwrap();
295-
assert!(!scope.is_allowed("/home/tauri/**"));
296-
assert!(scope.is_allowed("/home/tauri/**/file"));
297-
assert!(scope.is_allowed("/home/tauri/**/inner/file"));
298-
assert!(scope.is_allowed("/home/tauri/anyfile"));
357+
#[cfg(unix)]
358+
{
359+
scope.allow_directory("/home/tauri", false).unwrap();
360+
assert!(scope.is_allowed("/home/tauri/**"));
361+
assert!(!scope.is_allowed("/home/tauri/**/file"));
362+
assert!(!scope.is_allowed("/home/tauri/**/inner/file"));
363+
assert!(scope.is_allowed("/home/tauri/anyfile"));
364+
}
365+
#[cfg(windows)]
366+
{
367+
scope.allow_directory("C:\\home\\tauri", false).unwrap();
368+
assert!(scope.is_allowed("C:\\home\\tauri\\**"));
369+
assert!(!scope.is_allowed("C:\\home\\tauri\\**\\file"));
370+
assert!(!scope.is_allowed("C:\\home\\tauri\\**\\inner\\file"));
371+
assert!(scope.is_allowed("C:\\home\\tauri\\anyfile"));
372+
}
299373
}
300374
}

0 commit comments

Comments
 (0)