~repos /rust-embed

#rust#proc-macro#http

git clone https://pyrossh.dev/repos/rust-embed.git

rust macro which loads files into the rust binary at compile time during release and loads the file from the fs during dev.


02469a4d Peter John

1 year ago
Merge pull request #235 from Buckram123/symlinks-does-not-work-in-debug
examples/public/symlinks/main.js ADDED
@@ -0,0 +1 @@
1
+ ../main.js
impl/src/lib.rs CHANGED
@@ -141,7 +141,16 @@ fn dynamic(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, includ
141
141
  let canonical_file_path = file_path.canonicalize().ok()?;
142
142
  if !canonical_file_path.starts_with(#canonical_folder_path) {
143
143
  // Tried to request a path that is not in the embedded folder
144
+
145
+ // TODO: Currently it allows "path_traversal_attack" for the symlink files
146
+ // For it to be working properly we need to get absolute path first
147
+ // and check that instead if it starts with `canonical_folder_path`
148
+ // https://doc.rust-lang.org/std/path/fn.absolute.html (currently nightly)
149
+ // Should be allowed only if it was a symlink
150
+ let metadata = ::std::fs::symlink_metadata(file_path.as_path()).ok()?;
151
+ if !metadata.is_symlink() {
144
- return ::std::option::Option::None;
152
+ return ::std::option::Option::None;
153
+ }
145
154
  }
146
155
 
147
156
  if rust_embed::utils::is_path_included(&rel_file_path, INCLUDES, EXCLUDES) {
tests/include_exclude.rs CHANGED
@@ -9,7 +9,8 @@ fn get_works() {
9
9
  assert!(AllAssets::get("index.html").is_some(), "index.html should exist");
10
10
  assert!(AllAssets::get("gg.html").is_none(), "gg.html should not exist");
11
11
  assert!(AllAssets::get("images/llama.png").is_some(), "llama.png should exist");
12
+ assert!(AllAssets::get("symlinks/main.js").is_some(), "main.js should exist");
12
- assert_eq!(AllAssets::iter().count(), 6);
13
+ assert_eq!(AllAssets::iter().count(), 7);
13
14
  }
14
15
 
15
16
  #[derive(RustEmbed)]
@@ -36,8 +37,9 @@ struct ExcludeSomeAssets;
36
37
  fn excluding_some_assets_works() {
37
38
  assert!(ExcludeSomeAssets::get("index.html").is_none(), "index.html should not exist");
38
39
  assert!(ExcludeSomeAssets::get("main.js").is_some(), "main.js should exist");
40
+ assert!(ExcludeSomeAssets::get("symlinks/main.js").is_some(), "main.js symlink should exist");
39
41
  assert!(ExcludeSomeAssets::get("images/llama.png").is_none(), "llama.png should not exist");
40
- assert_eq!(ExcludeSomeAssets::iter().count(), 2);
42
+ assert_eq!(ExcludeSomeAssets::iter().count(), 3);
41
43
  }
42
44
 
43
45
  #[derive(RustEmbed)]
@@ -52,3 +54,15 @@ fn exclude_has_higher_priority() {
52
54
  assert!(ExcludePriorityAssets::get("images/llama.png").is_some(), "llama.png should exist");
53
55
  assert_eq!(ExcludePriorityAssets::iter().count(), 2);
54
56
  }
57
+
58
+ #[derive(RustEmbed)]
59
+ #[folder = "examples/public/symlinks"]
60
+ #[include = "main.js"]
61
+ struct IncludeSymlink;
62
+
63
+ #[test]
64
+ fn include_symlink() {
65
+ assert_eq!(IncludeSymlink::iter().count(), 1);
66
+ assert_eq!(IncludeSymlink::iter().next(), Some(std::borrow::Cow::Borrowed("main.js")));
67
+ assert!(IncludeSymlink::get("main.js").is_some())
68
+ }
tests/interpolated_path.rs CHANGED
@@ -19,7 +19,7 @@ fn iter_works() {
19
19
  assert!(Asset::get(file.as_ref()).is_some());
20
20
  num_files += 1;
21
21
  }
22
- assert_eq!(num_files, 6);
22
+ assert_eq!(num_files, 7);
23
23
  }
24
24
 
25
25
  #[test]
@@ -32,6 +32,6 @@ fn trait_works_generic_helper<E: rust_embed::RustEmbed>() {
32
32
  assert!(E::get(file.as_ref()).is_some());
33
33
  num_files += 1;
34
34
  }
35
- assert_eq!(num_files, 6);
35
+ assert_eq!(num_files, 7);
36
36
  assert!(E::get("gg.html").is_none(), "gg.html should not exist");
37
37
  }
tests/lib.rs CHANGED
@@ -28,7 +28,7 @@ fn iter_works() {
28
28
  assert!(Asset::get(file.as_ref()).is_some());
29
29
  num_files += 1;
30
30
  }
31
- assert_eq!(num_files, 6);
31
+ assert_eq!(num_files, 7);
32
32
  }
33
33
 
34
34
  #[test]
@@ -41,6 +41,6 @@ fn trait_works_generic_helper<E: rust_embed::RustEmbed>() {
41
41
  assert!(E::get(file.as_ref()).is_some());
42
42
  num_files += 1;
43
43
  }
44
- assert_eq!(num_files, 6);
44
+ assert_eq!(num_files, 7);
45
45
  assert!(E::get("gg.html").is_none(), "gg.html should not exist");
46
46
  }
tests/path_traversal_attack.rs CHANGED
@@ -11,3 +11,17 @@ struct Assets;
11
11
  fn path_traversal_attack_fails() {
12
12
  assert!(Assets::get("../basic.rs").is_none());
13
13
  }
14
+
15
+ #[derive(RustEmbed)]
16
+ #[folder = "examples/axum-spa/"]
17
+ struct AxumAssets;
18
+
19
+ // TODO:
20
+ /// Prevent attempts to access symlinks outside of the embedded folder.
21
+ /// This is mainly a concern when running in debug mode, since that loads from
22
+ /// the file system at runtime.
23
+ #[test]
24
+ #[ignore = "see https://github.com/pyrossh/rust-embed/pull/235"]
25
+ fn path_traversal_attack_symlink_fails() {
26
+ assert!(Assets::get("../public/symlinks/main.js").is_none());
27
+ }