Version sécurisée de Path.Combine
-
03-07-2019 - |
Question
J'ai un rootPath
auquel je fais confiance et un relativePath
que je n'ai pas. Je souhaite les combiner de manière à pouvoir être sûr que le résultat se trouve sous rootPath
et que l'utilisateur ne puisse pas utiliser ..
pour revenir au-delà du début. point. Je veux que le chemin relatif autorise des choses comme: hello \ .. \ world
== world
La solution
Pour développer: utilisez Path.Combine, appelez ensuite GetFullPath et vérifiez que ce résultat commence par rootPath.
Cela ne vous protégera pas contre les liens durs, mais cela devrait vous permettre d'attraper des choses simples comme les doubles points.
le code ci-dessus:
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");
}
Autres conseils
Vous pouvez simplement appeler Path.GetFullPath ()
et vérifier si cela commence par votre chemin de confiance
. Si vous avez tendance à la paranoïa, vérifiez également que rootPath
est enraciné.
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 du technophile.
Vous pouvez notamment compter le nombre de barres obliques inverses ( \
) et de doubles points ( ..
) et vous assurer que le nombre de doubles Le nombre de points est inférieur au nombre de barres obliques inverses. Pour aller au-dessus du rootPath
de votre structure de dossiers, vous aurez besoin d'au moins autant de barres obliques inverses que de doubles points. Ainsi, si vous autorisez uniquement les relativePath
avec au moins une autre barre oblique inversée, vous devriez être en sécurité.