Pergunta

Olá a todos, estou desenvolvendo um site de compartilhamento de fotos usando o CodeIgniter PHP quadro . A idéia é que as pessoas podem fazer upload de suas fotos, gerenciá-los (através de algum tipo de navegador de arquivos que lhes permite criar subpastas, arraste os arquivos ao redor, etc) e editá-los (algumas coisas básicas como redimensionamento, rotação e recorte para começar, e mais tarde, eu vou adicionar alguns recursos avançados).

Eu já implementou uma solução de terceira autenticação festa para CI ( Redux Authentication 2 Beta ) e agora estou integrando um gerenciador de arquivos JS / PHP ( AjaxExplorer ), mas o problema é que o backend PHP para gerenciar arquivos (mover, copiar, etc) é confiar demasiado na entrada do usuário das chamadas ajax. Por exemplo, ele está fazendo coisas como esta (simplificado para maior clareza):

move_uploaded_file($_FILES['upload']['tmp_name'], $root.$username.$_POST['destination_dir']);

Como você pode ver, há preocupações de segurança óbvias, uma vez que aceita cegamente qualquer caminho que o usuário lança em! Já posso ver alguém mandar algo como "../AnotherUser/", como o $ _POST [ 'destination_dir'] valor.

A minha pergunta é:? Qual é a melhor maneira de "sandbox" um usuário, a fim de permitir que apenas ele para gerenciar seus próprios dados Eu só validar + filtro das entradas, na esperança de pegar cada tentativa de intrusão? Existem quaisquer bibliotecas / pacotes dedicados a abordar esta questão específica?

Eu acho que este problema deve ser de alguma forma resolvido em qualquer projeto (maduro o suficiente), o que dá aos seus usuários o poder de gerenciar seus arquivos através de um navegador web, então eu esperava encontrar algumas orientações claras em torno deste (como há um grande número cerca de injeção SQL, XSS, CSRF, etc), mas eu acho que eu não estou usando as palavras corretas.

Foi útil?

Solução

Qual é a melhor maneira de "sandbox" um usuário, a fim de permitir que apenas ele para gerenciar seus próprios dados?

Permitir quaisquer nomes de arquivos / nomes de diretório que o usuário quer, mas simplesmente não usá-los no sistema de arquivos do lado do servidor. Em vez disso, escrever os nomes de caminho em um banco de dados com uma chave primária, e usar a chave primária como um nome de arquivo como ‘34256.dat’ em um diretório de armazenamento do plano (ou mesmo como um BLOB no banco de dados se você preferir). Em seguida, servir-se através de um script de download ou URL reescrita para fazer o desejado nome aparecer na URL.

Saneantes nomes de arquivos de entrada é duro . Detectando ‘..’ é apenas o começo. nomes muito longos; nomes demasiado curtos; combinações de ataque e de fuga pontos; combinações de ataque e de fuga espaços em branco; os diferentes separadores de diretório de diferentes plataformas; caracteres que são inválidos em algumas plataformas; caracteres de controlo; caracteres Unicode e as formas específicas do ambiente de resolvê-los; ADSs; nomes de arquivos ( ‘.htaccess’) ou extensões ( ‘php’, ‘.cgi’) que pode ser ‘especial’ para o seu servidor web; nomes de arquivos reservados de janelas ...

Você pode passar a vida inteira rastrear engraçado pequenas peculiaridades de regras filePath em várias plataformas, ou você pode simplesmente esquecê-la e usar o banco de dados.

Outras dicas

Eu não tenho certeza do que sua aparência destination_dir quiser, mas o que eu pensei foi atribuir teclas de diretórios, e em seguida, obter o diretório base nessa chave. Por exemplo:

//$_POST['destination_dir'] = '4hg43h5g453j45b3';
*_query('SELECT dir FROM destinations WHERE key = ? LIMIT 1'); //etc.

No entanto, você tem que chaves predefinir antes da mão. Outra alternativa poderia ser o oposto:. Md5 / sha1 a entrada e usar isso como o destination_dir, em seguida, armazenar essa chave no banco de dados com o rótulo associado

Não há biblioteca que eu saiba.
No entanto, no seu exemplo particular, tira todas as barras (costas) e pontos da corda e, em seguida, acrescentar uma barra para o fim de tudo, de que maneira o usuário não pode alterar pastas.

$destdir = str_replace(array('.', '/', '\\'), '', $_POST['destination_dir']); 
$destdir .= "/";
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top