Armazenando e servindo arquivos com segurança para vários clientes

8

Estamos trabalhando em um aplicativo Web, no qual (entre outros recursos) nossos usuários podem fazer upload de seus arquivos. No entanto, não podemos armazenar esses arquivos em nosso VPS porque o espaço de armazenamento é limitado, por isso decidimos seguir com o S3.

O principal problema é que devemos garantir que os usuários possam acessar apenas seus próprios dados. Portanto, mantemos a lista de arquivos em nosso banco de dados e a lista de usuários que têm acesso a eles. Nosso servidor pode facilmente decidir se um usuário tem ou não acesso a um arquivo. Mas como realmente servir os arquivos para os usuários?

Existem algumas possibilidades que eu já considerei, mas nenhuma delas parece ser a melhor.

1. Gerando (expirando) URLs assinados com PHP

Essa é uma abordagem muito simples, também é rápida, mas resulta em URLs muito muito feios e longos.

Aqui está como fazê-lo .

2. URLs ofuscados

Isto significa que podemos manter o público arquivos para leitura on S3, mas todos os arquivos são armazenados em difícil adivinhar pastas nomeadas como: 24fa0b8ef0ebb6e99c64be8092d3ede20000. No entanto, talvez este não seja o caminho mais seguro a seguir. Mesmo que você nunca consiga adivinhar o nome de uma pasta, depois de conhecê-lo (porque você realmente tem acesso a ele), poderá compartilhar esse link com qualquer pessoa (com qualquer pessoa não autorizada).

3. Baixe os arquivos através do nosso servidor

Isso significa que os arquivos não são servidos diretamente pelo S3, mas primeiro nosso servidor os lê e os serve com segurança. Nós realmente não queremos isso :)

4. Verificando o referenciador

A solução de URLs ofuscadas pode ser aprimorada "certificando-se" de que a solicitação vem do nosso servidor (você pode configurar o S3 para verificar o referenciador). No entanto, essa seria uma solução muito confiável, porque nem todos os navegadores enviam os dados do referenciador e também podem ser falsificados.

Qual é uma boa maneira de veicular arquivos do Amazon S3 com segurança para diferentes clientes?

Tamás Pap
fonte
1
Por que você se importa com o URL feio / longo? Você não está fazendo o usuário digitar, está?
ceejayoz
Eu realmente acredito que os URLs são parte da experiência do usuário, e nós não queremos que eles muito longo e feio :)
Tamás Pap
2
Segurança e estabilidade devem superar URLs bonitas nesse caso, eu diria. Estes não são permalinks para as postagens do blog.
ceejayoz

Respostas:

12

Isso está muito próximo de "Faça minha arquitetura de sistema" para você, mas suas quatro idéias são estudos de caso interessantes em segurança variável, então vamos executar suas opções e ver como elas se saem:


4. Verificando o referenciador

O referenciador é fornecido pelo cliente. Confiar nos dados de autenticação / autorização fornecidos pelo cliente praticamente invalida a segurança (posso apenas afirmar que fui enviado de onde você espera que eu seja).
Veredicto: idéia TERRIBAD - trivial para contornar.


3. Baixe os arquivos através do nosso servidor

Não é uma má idéia, desde que você esteja disposto a gastar a largura de banda para que isso aconteça, e seu servidor seja confiável.
Supondo que você já tenha resolvido o problema de segurança do seu servidor / aplicativo normal, essa é a opção mais segura que você apresentou.
Veredicto: Boa solução. Muito seguro, mas possivelmente abaixo do ideal se a largura de banda for um fator.


2. URLs ofuscados

Segurança através da obscuridade ? Mesmo? Não,
eu nem vou analisá-lo. Apenas não.
Veredicto: Se o nº 4 foi TERRIBAD, isso é TERRIWORSE, porque as pessoas nem precisam se esforçar para forjar um cabeçalho de referência. Adivinhe a sequência e ganhe um prêmio com todos os dados!


1. Gerando (expirando) URLs assinados com PHP

Esta opção possui um quociente de sucção bastante baixo.
Qualquer um pode clicar no URL e capturar os dados, o que é um não-não-seguro, mas você minimiza isso fazendo com que o link expire (desde que a vida do link seja curta o suficiente, a janela de vulnerabilidade é pequena).
A expiração do URL pode incomodar alguns usuários que desejam manter o link de download por um longo período de tempo ou que não obtêm o link em tempo hábil - isso é uma merda de experiência do usuário, mas pode valer a pena .
Veredicto : Não é tão bom quanto o número 3, mas se a largura de banda é uma grande preocupação, certamente é melhor que o número 4 ou o número 2.


O que eu faria?

Dadas essas opções, eu usaria o nº 3 - passe os arquivos pelo seu próprio servidor front-end e autentique como o seu aplicativo normalmente faz. Supondo que sua segurança normal seja bastante decente, essa é a melhor opção do ponto de vista de segurança.
Sim, isso significa mais uso de largura de banda no servidor e mais recursos para intermediários - mas você sempre pode cobrar um pouco mais por isso.

voretaq7
fonte
Esta é uma análise realmente útil e sou muito grata por isso. Outro grande benefício do nº 3 é que - como o URL de um arquivo nunca muda - podemos usar fortemente o cache do navegador. Obrigado novamente pelo seu tempo.
Tamás Pap
O @TamasPap é uma vantagem da terceira posição, para ter certeza - qual a vantagem depende de quão agressivamente você pode configurar o cache (e com que frequência as pessoas acessam esses arquivos em máquinas "novas").
voretaq7
4

Use as consultas pré-assinadas do Amazon S3 para veicular os objetos do S3 diretamente aos usuários depois de fazer a validação do usuário desejada. Este método cria uma URL com tempo limitado para o qual você pode redirecionar usuários.

Michael Hampton
fonte
0

Existe outra maneira também.

Você pode apontar um AWS CloudFront para o seu S3 Bucket e usar cookies assinados para veicular conteúdo com segurança para seus usuários finais.

Os usuários finais precisam fazer login no servidor para obter os cookies assinados, que serão enviados à CDN ao acessar qualquer arquivo.

prcoder
fonte