Uploads do S3 incompatíveis com criptografia do lado do servidor

Estou tentando migrar um servidor Discourse existente para um novo ambiente baseado em AWS, armazenando uploads no S3 em um bucket usando criptografia do lado do servidor com chaves gerenciadas pelo cliente (SSE-C). Durante o processo de restauração, os uploads não estão chegando ao S3 — cada upload falha. Com o uso criterioso de depuração tap|p, descobri que o upload está sendo feito, mas a validação do etag retornado está falhando porque o etag retornado do S3 após o upload é diferente a cada vez. Por exemplo, este é o valor de retorno da chamada put_object em duas tentativas diferentes de restauração:

# Execução 1
#
# Run 1
#
#<struct Aws::S3::Types::PutObjectOutput expiration=nil, etag="\"d49ec2006cfd6fe957af2f711edd9a4b\"", checksum_crc32=nil, checksum_crc32c=nil, checksum_sha1=nil, checksum_sha256=nil, server_side_encryption="aws:kms", version_id="xAF23wQ.zwpoxVmmGiTjxfX0svMZbHAe", sse_customer_algorithm=nil, sse_customer_key_md5=nil, ssekms_key_id="**redacted**", ssekms_encryption_context=nil, bucket_key_enabled=true, request_charged=nil>

# Execução 2:
#
# Run 2:
#
#<struct Aws::S3::Types::PutObjectOutput expiration=nil, etag="\"05edffee421c6aef950b3d4418ada293\"", checksum_crc32=nil, checksum_crc32c=nil, checksum_sha1=nil, checksum_sha256=nil, server_side_encryption="aws:kms", version_id="H2_8SVh.Yx2LKB4GIjhyPbVoj_.Vc1E2", sse_customer_algorithm=nil, sse_customer_key_md5=nil, ssekms_key_id="**redacted**", ssekms_encryption_context=nil, bucket_key_enabled=true, request_charged=nil>

(Eu sei que são os mesmos arquivos porque também estou imprimindo a soma MD5 do lado do cliente e as opções de solicitação put_object, que incluem o nome do arquivo)

Acontece que o cabeçalho de resposta ETag se comporta… de forma diferente ao usar SSE-C:

Objetos criptografados por criptografia do lado do servidor com chaves fornecidas pelo cliente (SSE-C) ou chaves do AWS Key Management Service (AWS KMS) (SSE-KMS) têm ETags que não são um resumo MD5 de seus dados de objeto.

A única maneira que encontro de fazer a verificação de integridade de uploads com SSE-C é enviar o cabeçalho de solicitação Content-MD5, e deixar o S3 fazer a detecção de corrupção. Observe também que a verificação de já enviado também quebrará ao usar SSE-C, mas pelo menos isso pode ser desativado usando SKIP_ETAG_VERIFY.

Não estou enviando um PR imediatamente porque existem duas maneiras diferentes de abordar isso:

  1. Apenas estender o SKIP_ETAG_VERIFY para abranger a verificação pós-upload, que é barata e improvisada, e exige que os usuários saibam que seu uso de SSE-C significa que eles terão que ativá-lo; ou
  2. Mudar para usar o cabeçalho Content-MD5 (preferencialmente sempre) para fazer a proteção de integridade do upload, que tem o benefício de funcionar para todos, ao custo de um PR muito maior.

(Como aparte, estou bastante perturbado que ninguém tenha encontrado isso antes — ninguém está usando Discourse com SSE-C para uploads?)

4 curtidas

Minha suposição é que “uploads seguros” é usado apenas em casos muito específicos, o que faz com que 99,8% de todos os uploads sejam servidos publicamente de qualquer maneira, o que torna inútil qualquer tipo de criptografia em repouso?

Você não está errado, Matt, esta é a primeira vez que isso é levantado, até onde eu sei.

O (2) parece ser a abordagem correta para mim, se você conseguir.

Caso contrário, acho que você não terá confiança de que todos os arquivos estão lá corretamente.

Depois que você tiver todos os uploads em seu bucket S3, a operação geral do Discourse está OK? Outras alterações são necessárias para o uso diário (pensando em coisas como inventário podem quebrar - talvez sejam necessárias alterações para URLs pré-assinadas, etc…)?

5 curtidas

Vou tentar resolver. Felizmente, encontrar tudo o que menciona “etag” deve ser suficiente para encontrar todos os locais de código que precisam ser alterados, e o conjunto de testes está bem organizado para que eu possa encontrar o que precisa ser executado e alterado com bastante facilidade.

Quanto a outras coisas que podem quebrar, ainda não consegui ter um site funcionando, e continuarei reportando/enviando PRs à medida que avanço. O inventário não deve quebrar, porque apenas o conteúdo do arquivo é criptografado, não os nomes. Provavelmente não descobrirei se os URLs pré-assinados quebrarão, pois não os estou usando.

3 curtidas

Acabei de abrir esta PR que remove a verificação de upload baseada em ETag durante a migração para S3. Acontece que ela é apenas usada durante a migração para S3; no upload regular, é apenas YOLO’d, o que tornou minha vida muito mais fácil. Com esta PR, e a PR de desativação de ACL como configuração do site submetida anteriormente, tenho um restore completo agora. Próximo passo: testar funcionalidades.

6 curtidas

Acho que isso foi mesclado agora. :partying_face:

1 curtida

Este tópico foi fechado automaticamente após 2 dias. Novas respostas não são mais permitidas.