Peter Bucher - Mein Experiment, meine Spielereien, meine Welt...   ·   Stefan Falz   ·   Jürgen Gutsch   ·   Golo Roden   ·   ASP.NET Zone   ·   Microsoft ASP.NET
Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

ASP.NET Sicherheit - Directory Traversal verhindern

Im Wikipedia Artikel ist schon gut und ausführlich beschrieben, was unter “Directory Traversal” zu verstehen ist, Zitat:

Unter Directory Traversal versteht man eine Sicherheitslücke in Web-Programmen wie z. B. einem Webserver oder einer Webanwendung, bei der durch Manipulation von Pfadangaben auf beliebige Dateien und Verzeichnisse zugegriffen werden kann, die dafür eigentlich nicht vorgesehen waren. Diese kann so ausgenutzt werden, dass sensible Daten wie Passwörter preisgegeben werden.

Was kann der Entwickler dagegen tun?
Im besten Fall eine Guid / Id benutzen, um Dateien anzusprechen, jedoch ist das eine Mehrarbeit und manchmal nicht gewollt.

Hier noch kurz ein Fall, der auf Directory Traversal anfällig ist:

string xmlBasePath = Server.MapPath(“~/App_Data/XmlData/”);
string xmlFilePath = Path.Combine(xmlBasePath, Request.QueryString[“filename”]);
XmlDocument document = new XmlDocument();
document.Load(xmlFilePath);

In diesem Fall sieht der Pfad am Schluss so aus: “C:\Pfad\Zum\Web\App_Data\..\bild.xml”
Wie man sieht, ist das Zurückgehen per “../” noch nicht aufgelöst, dies macht entweder Server.MapPath() oder bspw. auch andere Parteien wie bspw. XmlDocument innerhalb der Load()-Methode.

Server.MapPath() wurde im oberen Beispiel aber nur für die Auflösung des Basispfades genutzt, darum hat sie keinen Einfluss.
Beim nächsten Beispiel ist wieder die selbe Situation, nur das hier Server.MapPath() den Pfad auflöst:

string xmlBasePath = “~/App_Data/XmlData/”;
string filePath = Server.MapPath(Path.Combine(xmlBasePath, Request.QueryString[“filename”]));
// weiterer Code…..

Der Wert vom Benutzer – also Request.QueryString[“filename”] – kann also eine “../” Zeichenfolge vor dem Dateinamen selber enthalten und evt. sogar andere Pfadangaben.

Wenn der Benutzer richtig böse ist, kann er so versuchen an einen anderen Ort innerhalb des Webs oder – bei schlechten Sicherheitseinstellungen – sogar des Webservers zu gelangen.

Die simpelste Abwehrmethode ist das Ersetzen von allen möglichen Vorkommnissen von “../”.
Jedoch ist das mühsam und immer noch nicht 100% sicher, denn über eine Eingabe von “/secureimages/image.jpg” kommt der Benutzer immer noch an eine Datei in einem geschützten Unterordner(App_Data ist grundsätzlich geschützt) ran.

Das denkbar schlimmste Horroszenario wäre die Übernahme einer Datenbank oder oder sogar des Servers, was so durchaus machbar wäre.

Die einfachste und zugleich auf effektivste Abwehrmassnahme ist die Benutzung von Path.GetFileName(<Wert vom Benutzer>);

Im oben stehenden Wikipedia Artikel ist noch beschrieben, dass auch Url kodierte Zeichen genutzt werden können und dann die erste hier vorgestellte Lösung unwirksam wird.
Dies muss bei ASP.NET nicht beachtet werden, da bei Request.QueryString[] immer “../” ankommt, die Methode dekodiert also die Werte in der Url schon.

Ein angriffssicheres Beispiel sieht dann so aus:

string xmlBasePath = Server.MapPath(“~/App_Data/XmlData/”);
string xmlFileName = Path.GetFileName(Request.QueryString[“filename”]);
string xmlFilePath = Path.Combine(xmlBasePath, xmlFileName);

XmlDocument document = new XmlDocument();
document.Load(xmlFilePath);

Veröffentlicht Samstag, 15. August 2009 13:12 von Peter Bucher

Kommentare

Keine Kommentare
Anonyme Kommentare sind nicht zugelassen