diff --git a/doc/contributions.txt b/doc/contributions.txt
index 2272ec79227bb7ce193c1bef60e8345b046cd7b1..eb012ee31846d3af4edb2ce49f55e2a49483b9c5 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -771,6 +771,8 @@ Kadah Coba
 	STORM-1060
     STORM-1843
 Jondan Lundquist
+Joosten Briebers
+    MAINT-7074
 Josef Munster
 Josette Windlow
 Juilan Tripsa
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 86a15f2ef2c4e1a9a6764fb4a2e55d3b4fdddf1c..924e1166ee44608706b760d68070a53604587b14 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -720,6 +720,15 @@ std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,
 					   << ((constraint == CURRENT_SKIN)? "CURRENT_SKIN" : "ALL_SKINS")
 					   << LL_ENDL;
 
+	// Build results vector.
+	std::vector<std::string> results;
+	// Disallow filenames that may escape subdir
+	if (filename.find("..") != std::string::npos)
+	{
+		LL_WARNS("LLDir") << "Ignoring potentially relative filename '" << filename << "'" << LL_ENDL;
+		return results;
+	}
+
 	// Cache the default language directory for each subdir we've encountered.
 	// A cache entry whose value is the empty string means "not localized,
 	// don't bother checking again."
@@ -784,8 +793,6 @@ std::vector<std::string> LLDir::findSkinnedFilenames(const std::string& subdir,
 		}
 	}
 
-	// Build results vector.
-	std::vector<std::string> results;
 	// The process we use depends on 'constraint'.
 	if (constraint != CURRENT_SKIN) // meaning ALL_SKINS
 	{