2009-04-29 8 views
2

J'ai un rootPath que j'ai confiance et un relativePath que je n'ai pas. Je veux les combiner de telle sorte que je peux être sûr que le résultat est sous rootPath et que l'utilisateur ne peut pas utiliser .. pour revenir au-delà du point de départ. Je ne veulent le chemin relatif pour permettre des choses comme: hello\..\world == worldVersion sûre de Path.Combine

Répondre

5

System.IO.Path.GetFullPath?

Pour développer: utilisez Path.Combine, puis appelez GetFullPath sur le résultat et vérifiez que ce résultat commence par rootPath.

Il ne vous protégera pas contre les liens physiques, mais il devrait attraper des choses simples comme les points doubles.

ci-dessus code:

string Resolve(string fileName) 
{ 
    string root = FileRoot(); 
    string ret = Path.GetFullPath(Path.Combine(root, fileName)); 
    if (ret.StartsWith(root.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar)) return ret; 
    throw new ArgumentException("path resolved to out of accesable directroy"); 
} 
+0

J'aime: D – BCS

+3

Cependant, si root ne se termine pas par \, c'est encore possible de jouer un tour limité - se retrouver dans un répertoire différent, un frère de la racine, qui commence avec cela comme un préfixe. Par exemple, root peut être \ zip \ zop, chemin relatif .. \ zopper \ zup, vous vous retrouvez dans \ zip \ zopper \ zup, en dehors de l'arborescence racine de \ zip \ zop mais satisfaisant toujours au test StartsWith. Petit risque, mais pas nul. –

+1

Belle affaire de coin ... va ajouter ça au code. –

-1

Une chose que vous pouvez faire est de compter le nombre de barres obliques inverses (\) et double-points (..), et assurez-vous que le nombre de doubles points est plus petit que le nombre de barres obliques inverses. Pour dépasser la rootPath dans votre structure de dossiers, vous aurez besoin d'au moins autant de barres obliques inverses que de doubles points. Ainsi, si vous n'autorisez que relativePath avec au moins une barre oblique inverse, vous devriez être en sécurité.

+0

mais \ .. \ .. \ this \ goes \ who \ knowns \ où – BCS

+0

Je pense que vous finissez par avoir besoin de garder un compte courant – BCS

2

Vous pouvez simplement appeler Path.GetFullPath() et vérifier si elle commence par votre confiance rootPath. Si vous avez tendance à la paranoïa, vérifiez également que rootPath est enracinée.

public Boolean IsPathSafe(String rootPath, String relativePath) 
{ 
    return rootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) && 
    Path.IsPathRooted(rootPath) && 
    Patch.Combine(rootPath, relativePath).GetFullPath().StartsWith(rootPath); 
} 

Pour une explication du premier test, voir le commentaire d'Alex Martelli sur la réponse de technophile.

Questions connexes