Treat backslash as a path separator in XModem filename validation (#11085)
This commit is contained in:
co-authored by
GitHub
parent
19ddadf3ff
commit
ba8b1b1038
+4
-1
@@ -62,10 +62,13 @@ bool XModemAdapter::isValidFilename(const char *name)
|
|||||||
{
|
{
|
||||||
if (!name || name[0] == '\0')
|
if (!name || name[0] == '\0')
|
||||||
return false;
|
return false;
|
||||||
|
const bool driveLetter = (name[0] >= 'A' && name[0] <= 'Z') || (name[0] >= 'a' && name[0] <= 'z');
|
||||||
|
if (driveLetter && name[1] == ':')
|
||||||
|
return false;
|
||||||
// Reject any ".." path component. Absolute paths and subdirectories are fine; they stay within
|
// Reject any ".." path component. Absolute paths and subdirectories are fine; they stay within
|
||||||
// the filesystem root, so only traversal out of it needs blocking.
|
// the filesystem root, so only traversal out of it needs blocking.
|
||||||
for (const char *seg = name; *seg;) {
|
for (const char *seg = name; *seg;) {
|
||||||
const char *slash = strchr(seg, '/');
|
const char *slash = strpbrk(seg, "/\\");
|
||||||
const size_t len = slash ? (size_t)(slash - seg) : strlen(seg);
|
const size_t len = slash ? (size_t)(slash - seg) : strlen(seg);
|
||||||
if (len == 2 && seg[0] == '.' && seg[1] == '.')
|
if (len == 2 && seg[0] == '.' && seg[1] == '.')
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -21,6 +21,22 @@ void test_xmodem_rejects_dotdot_traversal(void)
|
|||||||
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("/.."));
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("/.."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_xmodem_rejects_backslash_traversal(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("..\\secret"));
|
||||||
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("..\\..\\Windows\\System32\\drivers\\etc\\hosts"));
|
||||||
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("dir\\..\\..\\x"));
|
||||||
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("dir/..\\x"));
|
||||||
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("dir\\.."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_xmodem_rejects_drive_qualified(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("C:\\Windows\\System32\\x"));
|
||||||
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("C:/Windows/System32/x"));
|
||||||
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename("c:relative.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
void test_xmodem_rejects_empty(void)
|
void test_xmodem_rejects_empty(void)
|
||||||
{
|
{
|
||||||
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename(""));
|
TEST_ASSERT_FALSE(XModemAdapter::isValidFilename(""));
|
||||||
@@ -36,6 +52,9 @@ void test_xmodem_allows_legit_paths(void)
|
|||||||
// ".." only inside a name (not a whole component) is a valid filename, not traversal.
|
// ".." only inside a name (not a whole component) is a valid filename, not traversal.
|
||||||
TEST_ASSERT_TRUE(XModemAdapter::isValidFilename("my..file"));
|
TEST_ASSERT_TRUE(XModemAdapter::isValidFilename("my..file"));
|
||||||
TEST_ASSERT_TRUE(XModemAdapter::isValidFilename("..."));
|
TEST_ASSERT_TRUE(XModemAdapter::isValidFilename("..."));
|
||||||
|
// A colon that cannot form a drive qualifier is a legal filename on the POSIX daemon.
|
||||||
|
TEST_ASSERT_TRUE(XModemAdapter::isValidFilename("1:30pm.txt"));
|
||||||
|
TEST_ASSERT_TRUE(XModemAdapter::isValidFilename("dir/1:30pm.txt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FSCom
|
#endif // FSCom
|
||||||
@@ -46,6 +65,8 @@ void setup()
|
|||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
RUN_TEST(test_xmodem_rejects_dotdot_traversal);
|
RUN_TEST(test_xmodem_rejects_dotdot_traversal);
|
||||||
|
RUN_TEST(test_xmodem_rejects_backslash_traversal);
|
||||||
|
RUN_TEST(test_xmodem_rejects_drive_qualified);
|
||||||
RUN_TEST(test_xmodem_rejects_empty);
|
RUN_TEST(test_xmodem_rejects_empty);
|
||||||
RUN_TEST(test_xmodem_allows_legit_paths);
|
RUN_TEST(test_xmodem_allows_legit_paths);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user