diff options
| author | Admiral H. Curtiss <pikachu025@gmail.com> | 2022-06-16 04:15:28 +0200 |
|---|---|---|
| committer | Admiral H. Curtiss <pikachu025@gmail.com> | 2022-07-11 23:11:42 +0200 |
| commit | f40eeebcf0d768a2f6400186b25b3e51e9531610 (patch) | |
| tree | df34d5fe0f9f9b2b3a62427bc12f3f3e3c3a3a50 /Source/Core/Common/FatFsUtil.cpp | |
| parent | a621fdf857460d0cb4cb493fd5dc4f3b69d37295 (diff) | |
FatFsUtil: Add some path traversal attack protection when unpacking.
Diffstat (limited to 'Source/Core/Common/FatFsUtil.cpp')
| -rw-r--r-- | Source/Core/Common/FatFsUtil.cpp | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/Source/Core/Common/FatFsUtil.cpp b/Source/Core/Common/FatFsUtil.cpp index 7e0c2e2a21..a3230f2cc6 100644 --- a/Source/Core/Common/FatFsUtil.cpp +++ b/Source/Core/Common/FatFsUtil.cpp @@ -8,8 +8,11 @@ #include <cstdlib> #include <mutex> #include <string> +#include <string_view> #include <vector> +#include <fmt/format.h> + // Does not compile if diskio.h is included first. // clang-format off #include "ff.h" @@ -439,8 +442,21 @@ static bool Unpack(const std::string path, bool is_directory, const char* name, if (entry.fname[0] == '\0') break; - if (!Unpack(path + "/" + entry.fname, entry.fattrib & AM_DIR, entry.fname, tmp_buffer)) + const std::string_view childname = entry.fname; + + // Check for path traversal attacks. + if (childname.find("\\") != std::string_view::npos) + return false; + if (childname.find('/') != std::string_view::npos) + return false; + if (std::all_of(childname.begin(), childname.end(), [](char c) { return c == '.'; })) + return false; + + if (!Unpack(fmt::format("{}/{}", path, childname), entry.fattrib & AM_DIR, entry.fname, + tmp_buffer)) + { return false; + } } if (f_closedir(&directory) != FR_OK) |
