Prevenção de passagem de diretório em PHP, mas permitindo ca

Segurança em PHP e seus frameworks
Márcio Rossi
Posts: 21
Joined: 09 Dec 2014 12:21

Prevenção de passagem de diretório em PHP, mas permitindo ca

Post by Márcio Rossi » 12 Dec 2014 13:25

Eu tenho um caminho de base / whatever / foo /

e
$ _GET ['Caminho'] deve ser relativo a ela.

No entanto como faço para conseguir isso (a leitura do diretório), sem permitir a passagem de diretório?

por exemplo.

/\.\.|\.\./


Não irá filtrar adequadamente.

Alexandre Medeiros
Posts: 27
Joined: 02 Dec 2014 17:38

Re: Prevenção de passagem de diretório em PHP, mas permitind

Post by Alexandre Medeiros » 12 Dec 2014 13:25

Bem, uma opção seria comparar os caminhos reais:

$ BasePath = '/ foo / bar / base /;
$ Realbase = realpath ($ BasePath);

$ Userpath = $ BasePath. $ _GET ['Caminho'];
$ RealUserPath = realpath ($ userpath);

if ($ realUserPath === falsos || strpos ($ realUserPath, $ Realbase)! == 0) {
// Passagem de diretório!
} Else {
// Bom caminho!
}


Basicamente, realpath () irá resolver o caminho fornecido em um caminho físico real rígido (resolução de links simbólicos, ..,., /, //, Etc) ... Então, se o caminho do usuário real não começa com o caminho base real, ele está tentando fazer a travessia. Note-se que a saída do realpath não tem nenhum "diretórios virtuais", como. ou .....

A Leopold
Posts: 11
Joined: 09 Dec 2014 12:44

Re: Prevenção de passagem de diretório em PHP, mas permitind

Post by A Leopold » 12 Dec 2014 13:26

ircmaxell a resposta não era totalmente correta. Eu vi que a solução em vários trechos, mas tem um bug que está relacionada com a saída do realpath (). O realpath function () remove o separador de diretório à direita, então imagine dois diretórios contíguos, tais como:

/ Foo / bar / base /

/ Foo / bar / baz_baz /

Como realpath () iria remover o último separador de diretório que você método irá retornar "bom caminho" if $ _GET ['caminho'] foi igual a "../baz_baz", pois seria algo como

strpos ("/ foo / bar / baz_baz", "/ foo / bar / base")


Pode Ser:

$ BasePath = '/ foo / bar / base /;
$ Realbase = realpath ($ BasePath);

$ Userpath = $ BasePath. $ _GET ['Caminho'];
$ RealUserPath = realpath ($ userpath);

if ($ realUserPath === false strcmp || ($ realUserPath, $ Realbase)! == 0 || strpos ($ realUserPath, $ Realbase. DIRECTORY_SEPARATOR)! == 0) {
// Passagem de diretório!
} Else {
// Bom caminho!
}

BUTTON_POST_REPLY