Link Search Menu Expand Document

Unrestricted File Download in Python

Vulnerable Example

The snippet below is a helper function used to concatenate the directory that contains the asset files, /opt/wwwdata/assets/ with the file name passed as assetName.

using System;

public class Assets
{
  public static string assetsDir = "/opt/wwwdata/assets/";

  public static string getAssetPath(string assetName)
  {
    return System.IO.Path.Combine(
      assetsDir, 
      assetName
    );
  }
}

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

To validate that a path does not point to an unintended location, use Path.GetFullPath() to get the absolute path, and then validate it starts as expected.

public static string getAssetPath(string assetName)
{
  string assetPath = System.IO.Path.Combine(
    assetsDir, 
    assetName
  );
  
  if(!Path.GetFullPath(assetPath).StartsWith(assetsDir)) {
    throw new System.InvalidOperationException("Provided asset name is invalid");
  }
  
  return assetPath;
}

To sanitize the path, it is possible to use System.IO.Path.GetFileName() to concatenate only the final part of the user-provided file name.

public static string getAssetPath(string assetName)
{
  return System.IO.Path.Combine(
    assetsDir, 
    System.IO.Path.GetFileName(assetName)
  );
}

The previous attack would result in reading the /opt/wwwdata/assets/passwd file.

References

Owasp - Path Traversal