Pergunta

Eu tenho um rootPath que eu confio e uma relativePath que eu não. Eu quero combiná-los de tal maneira que eu posso ter certeza de que o resultado está sob rootPath e que o usuário não pode usar .. para voltar passado o ponto de partida. I não quer o caminho relativo para permitir que coisas como: hello\..\world == world

Foi útil?

Solução

System.IO.Path.GetFullPath ?

Para expandir:. Uso Path.Combine, em seguida, chamar GetFullPath no resultado e verificar se esse resultado começa com rootPath

Ele não vai protegê-lo contra hardlinks, mas deve pegar coisas simples como duplas pontos.

acima como código:

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

Outras dicas

Você poderia simplesmente chamar Path.GetFullPath() e verificar se ele começa com a sua rootPath confiável. Se você tende a paranóia, verificar também que rootPath está enraizada.

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

Para uma explicação do primeiro teste ver o comentário de Alex Martelli sobre a resposta de technophile.

Uma coisa que você pode fazer é contar o número de barras invertidas (\) e double-pontos (..), e certifique-se que o número de duplas-pontos é menor do que o número de barras invertidas. A fim de ir acima da rootPath em sua estrutura de pastas, você precisará de pelo menos tantas barras invertidas como pontos duplos -. Assim, se você só permitem relativePaths com pelo menos mais uma barra invertida, você deve ser seguro

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top