Unrestricted File Download in Scala
Vulnerable Example
The snippet below provides a helper function used to concatenate the directory that contains the asset files /opt/wwwdata/assets/
with the file name passed as assetName
.
object Util {
val assetsDir = "/opt/wwwdata/assets/"
def getAssetPath(assetName: String) {
val path = new File(assetsDir, assetName)
return path.toString();
}
}
If assetName
is controlled by the user, it is possible to conduct a path traversal attack and escape the intended directory, for example, by using ../../../../../../etc/passwd
as file asset name.
This results in the absolute path /opt/wwwdata/assets/../../../../../etc/passwd
which is canonicalized by the operating system as /etc/passwd
.
Prevention
When building the final path, using only the final fragment of the user-provided value is often enough, and the getName()
method of the File
instances does exactly that. So, for example, the utility class becomes:
object Util {
val assetsDir = "/opt/wwwdata/assets/"
def getAssetPath(assetName: String) {
val safeAssetName = new File(assetName).getName()
val path = new File(assetsDir, safeAssetName)
return path.toString();
}
}
The previous attack would result in the /opt/wwwdata/assets/passwd
file being read.