Publicando backups de banco de dados sem expor informações privadas de usuários

No bitcoincashresearch.org, estamos buscando oferecer um certo nível de descentralização do fórum, incluindo a possibilidade de que qualquer pessoa que considere necessário possa recriar uma determinada instância do fórum em outro domínio.

Para que isso seja possível, devemos publicar backups do banco de dados periodicamente. No entanto, enfrentamos o problema de expor informações privadas dos usuários, como e-mails, endereços IP, etc.

Podemos remover essas informações privadas dos backups do banco de dados manualmente, mas isso não parece ser a opção mais inteligente ou mais limpa, especialmente com backups periódicos.

Vocês conhecem alguma solução que possa funcionar nesse sentido? Ou algum exemplo de algo semelhante que já tenha sido feito?

Esse é um caso de borda bastante estranho!

Você gostaria de remover IPs e endereços de e-mail? Sem endereços de e-mail, não haveria como os usuários recuperarem suas contas (se usassem uma senha, poderiam fazer login, mas não conseguiriam colocar o endereço de e-mail de volta, pois não haveria como validar a alteração).

Não vejo como criar um backup útil que não contenha pelo menos os endereços de e-mail.

Aqui estão dumps públicos em SQL de um fórum Discourse: Index: if-archive/info/intficforum

Você pode tirar algumas ideias de lá.

Concordo que pode parecer um caso de borda estranho. Mas a ideia por trás disso não parece tão ruim, já que ajuda a evitar a centralização do fórum.
Entendo que isso pode não ser muito importante para alguns fóruns, mas pode ser para outros.
Também concordo que remover usuários e senhas (entre outras informações) do backup impediria que esses mesmos usuários fizessem login na nova instância.
É por isso que disse que não parecia a maneira mais inteligente.
Provavelmente deveria reformular minha pergunta.
Existe algum método conhecido ou procedimento recomendado para publicar backups de banco de dados de modo que qualquer pessoa possa reconstruir uma determinada instância do fórum sem expor informações privadas dos usuários?

Gostaria de adicionar um pouco de contexto. Existe uma necessidade / caso de uso muito específico.

Há um discurso operacional com conteúdo importante, e esse conteúdo se tornará cada vez mais relevante com o tempo. Devido à natureza do ecossistema que o utiliza, evitar pontos únicos de falha é algo que aprendemos ser extremamente importante.

Com uma exportação hoje, se você excluir as informações de autenticação, seria possível publicar publicamente todo o conteúdo do site. No entanto, como @pfaffman apontou, isso resulta em uma ruptura irreversível: os usuários não conseguem mais autenticar-se e o site exportado torna-se apenas de leitura.

Portanto, acho que o que Leandro precisa é de um recurso no Discourse que permita aos usuários fazer login por meio de desafios criptográficos, em vez dos esquemas tradicionais de conta/senha. Na exportação, incluiríamos apenas essa parte da conta — nenhuma das outras informações, como e-mail, hashes de senha, etc. Na cópia alternativa do site, os usuários que aproveitaram esse recurso poderiam fazer login e seguir um procedimento padrão de recuperação de conta por e-mail.

Ao realizar essa publicação completa, será obviamente muito importante não incluir nenhuma das informações tradicionais de autenticação de conta, como e-mails e hashes de senha, etc. Isso é tão crucial que, para qualquer versão do Discourse com esse recurso, as informações sensíveis devem ser mantidas em um local separado do restante dos dados do site, tornando impossível exportá-las acidentalmente.

Espero que isso ofereça um pouco mais de contexto para refletir.

Além disso, essas mudanças são obviamente muito complexas. Seria bom receber feedback, relatos de problemas e alternativas. Talvez seja possível reunir recursos do lado do nosso ecossistema para criar um fork que implemente a ideia.

Isso pode ser feito adicionando suporte ao WebAuthn como um método de autenticação sem senha, conforme explicado em Suporte ao WebAuthn.

Isso, mais um serviço para limpar o arquivo de backup dos campos que você não deseja expor.

Essa é outra solução para o login.

Ah, e usuários comuns não precisam aprovar alterações de endereço de e-mail se estiverem logados, então um dump com os endereços de e-mail removidos seria aceitável para todos os usuários que devem fazer login usando as credenciais que estão no banco de dados (a senha é a mais fácil).

Um plugin que remova os endereços de e-mail ou os criptografe (acho que sei como fazer isso com relativa facilidade) resolveria o problema.

Em um plugin, eu criptografei alguns campos assim:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/models/pfaffmanager/server.rb#L9-L10

Acho que pode ser possível sobrescrever o modelo UserEmail de forma semelhante e criptografar os endereços de e-mail. Não há muito código no modelo UserEmail e suspeito que ele mude com pouca frequência, então talvez não seja uma alteração muito perigosa. Ou pode não funcionar de jeito nenhum.

Filtrar endereços IP pode ser um pouco mais complicado, pois acho que seria difícil sobrescrever o modelo de usuário. Para isso, você pode criar um plugin que remova esses IPs de uma forma ou de outra.

@Falco e @pfaffman, muito obrigado pelo feedback e pelas dicas.

Vamos investigar o Webauthn para ver se podemos seguir por esse caminho, assim como faremos com seu plugin, @pfaffman.

Retornarei em alguns dias com alguns comentários, perguntas ou conclusões.

Outra possibilidade no horizonte é o uso de um PAKE (Password-Authenticated Key Exchange) Aumentado, para que a senha seja praticamente irrecuperável do banco de dados e nunca toque na rede.

Infelizmente, todas elas ainda estão firmemente no domínio da criptografia experimental e não estão prontas para implantação fácil. A sincronização do iCloud no iOS usa um PAKE.

Se você deseja manter o login com e-mail/senha, mas de forma que qualquer pessoa possa acessar a conta de qualquer usuário no banco de dados de backup, você pode fazer isso gerando um e-mail baseado no nome de usuário para cada usuário, como <username>@email.invalid.

Para senhas e logins, assumindo que o Discourse use senhas criptografadas com salts (não verifiquei, mas assumo que sim), você pode definir uma senha como 123456 (no seu banco de dados em produção), verificar no banco de dados a senha criptografada resultante, bem como o salt (depois mude sua senha de volta, ou faça isso em uma conta falsa). Em seguida, execute um comando no novo banco de dados (clonado) para definir as senhas criptografadas e os salts de todos os usuários com os valores que você viu anteriormente (cada usuário terá a mesma senha criptografada e o mesmo salt e, consequentemente, a mesma senha, aquela que você usou antes). Assim, para um usuário foo, você poderá fazer login com o e-mail foo@email.invalid e a senha 123456.

Além disso, talvez você queira excluir as mensagens privadas (se não forem necessárias), pois elas podem conter dados sensíveis.

E, finalmente, é bom verificar campos que possam conter dados confidenciais, como as configurações (de administrador).