Pregunta

Tengo un rootPath en el que confío y un relativePath que no tengo. Quiero combinarlos de tal manera que pueda estar seguro de que el resultado está en rootPath y que el usuario no puede usar .. para volver más allá del inicio punto. do quiero que la ruta relativa permita cosas como: hello \ .. \ world == world

¿Fue útil?

Solución

System.IO.Path.GetFullPath ?

Para expandir: use Path.Combine, luego llame a GetFullPath en el resultado y verifique que ese resultado comience con rootPath.

No te protegerá contra enlaces duros, pero debería detectar cosas simples como puntos dobles.

el código anterior:

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");
}

Otros consejos

Puede llamar a Path.GetFullPath () y verificar si comienza con su rootPath de confianza. Si tiendes a la paranoia, comprueba también que rootPath está enraizado.

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

Para una explicación de la primera prueba, vea el comentario de Alex Martelli sobre la respuesta del tecnófilo.

Una cosa que puedes hacer es contar el número de barras invertidas ( \ ) y los puntos dobles ( .. ), y asegurarte de que el número de dobles los puntos son más pequeños que la cantidad de barras invertidas. Para ir por encima de rootPath en su estructura de carpetas, necesitará al menos tantas barras diagonales invertidas como puntos dobles, por lo tanto, si solo permite relativePath con al menos Una barra invertida más, debería estar seguro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top