~repos /rust-embed
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.
51ee3fa6
—
Peter John 4 years ago
Merge pull request #160 from pyros2097/fix/path-traversal-attack
- impl/src/lib.rs +11 -1
- tests/path_traversal_attack.rs +13 -0
impl/src/lib.rs
CHANGED
|
@@ -98,6 +98,9 @@ fn dynamic(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, includ
|
|
|
98
98
|
const excludes: &[&str] = &[#(#excludes),*];
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
+
let canonical_folder_path = Path::new(&folder_path).canonicalize().expect("folder path must resolve to an absolute path");
|
|
102
|
+
let canonical_folder_path = canonical_folder_path.to_str().expect("absolute folder path must be valid unicode");
|
|
103
|
+
|
|
101
104
|
quote! {
|
|
102
105
|
#[cfg(debug_assertions)]
|
|
103
106
|
impl #ident {
|
|
@@ -111,8 +114,15 @@ fn dynamic(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, includ
|
|
|
111
114
|
let rel_file_path = file_path.replace("\\", "/");
|
|
112
115
|
let file_path = std::path::Path::new(#folder_path).join(&rel_file_path);
|
|
113
116
|
|
|
117
|
+
// Make sure the path requested does not escape the folder path
|
|
118
|
+
let canonical_file_path = file_path.canonicalize().ok()?;
|
|
119
|
+
if !canonical_file_path.starts_with(#canonical_folder_path) {
|
|
120
|
+
// Tried to request a path that is not in the embedded folder
|
|
121
|
+
return None;
|
|
122
|
+
}
|
|
123
|
+
|
|
114
124
|
if rust_embed::utils::is_path_included(&rel_file_path, includes, excludes) {
|
|
115
|
-
rust_embed::utils::read_file_from_fs(&
|
|
125
|
+
rust_embed::utils::read_file_from_fs(&canonical_file_path).ok()
|
|
116
126
|
} else {
|
|
117
127
|
None
|
|
118
128
|
}
|
tests/path_traversal_attack.rs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
use rust_embed::RustEmbed;
|
|
2
|
+
|
|
3
|
+
#[derive(RustEmbed)]
|
|
4
|
+
#[folder = "examples/public/"]
|
|
5
|
+
struct Assets;
|
|
6
|
+
|
|
7
|
+
/// Prevent attempts to access files outside of the embedded folder.
|
|
8
|
+
/// This is mainly a concern when running in debug mode, since that loads from
|
|
9
|
+
/// the file system at runtime.
|
|
10
|
+
#[test]
|
|
11
|
+
fn path_traversal_attack_fails() {
|
|
12
|
+
assert!(Assets::get("../basic.rs").is_none());
|
|
13
|
+
}
|