Segurança lógica sobre ações do Usuário Atual

E aí! Tudo bem!?

Tenho trabalhado em segurança lógica com base nas informações do usuário atual, como if this.topic.creator.username === User.current().username, para permitir que o usuário edite ou exclua o tópico.

O ponto é: preciso garantir certas ações com base na sessão do usuário! Mas tenho feito alguns testes e é por isso que estou aqui perguntando a vocês.

Através do JavaScript no navegador (mesmo em modo de produção), é possível executar Discourse.User.current().set('username', 'sometestename'). Dessa forma, algumas ações no meu sistema seriam habilitadas apenas com essa alteração. Sei que esse não é o objetivo de 99% dos usuários, mas, além desse caso, vocês conhecem alguma maneira de garantir que o usuário não manipule as informações dele?

Atenciosamente,
Felipe

Se você alterar informações no seu navegador local, isso não muda nada no back-end.

O usuário está logado por meio de um token de autenticação, creio eu, então você não pode se passar por outra pessoa para o back-end:

Como não é possível enganar o servidor, você não conseguirá fazer nenhuma alteração como outro usuário.

Assim que você atualizar o navegador, suas alterações locais provavelmente serão apagadas. No pior caso, você provavelmente vai corromper o estado da aplicação JavaScript e terá que limpar o cache.

E aí! É isso!

Como você disse, a melhor maneira seria sempre obter a sessão do usuário atual no servidor back-end.

Dessa forma, as alterações de cache no navegador não teriam efeito! Você sabe onde posso verificar se a segurança lógica é baseada na sessão do usuário no servidor back-end e não no PreloadStore?

Me avise se eu estiver seguindo o caminho errado! Obrigado, Robert, pela ajuda!

Atenciosamente,
Felipe

Não sou especialista em segurança, apenas desenvolvedor de aplicativos, mas todas as alterações persistentes só podem ser feitas no servidor. O que acontece no navegador no EmberJS é para conveniência do usuário e uma experiência de usabilidade superior, como cache para velocidade e comportamento de interface semelhante ao de um aplicativo, quase automático. Isso não muda o fato de que, em última análise, ele precisa negociar todas as alterações persistentes com o servidor Rails e, ao fazê-lo, terá permissão para isso apenas para o usuário logado.

O mesmo vale para toda a recuperação de dados: o servidor Rails só enviará dados aos quais o usuário logado tem acesso.

Acho que você não precisa se preocupar com isso, porque, se alguém tentasse subverter isso, esbarraria no primeiro obstáculo: não há como enganar a API.

Qual é a sua preocupação?

Estou preocupado porque estou trabalhando em algumas abordagens em que tal ação estará disponível ou não dependendo do seu usuário: se você é o criador do tópico, se é o criador da postagem. Assim, preciso validar com base na sessão do usuário no backend.

Como isso, na postagem, o usuário pode editá-la se for o criador da postagem.

EDIT: Como as permissões de postagem do Discourse, vou verificar.

Atenciosamente, Felipe

Você deve desenvolver todas as medidas de segurança primeiramente no back end.

Os serializers do Rails determinam quais dados são enviados.

O Guardian protege quais ações são permitidas.

Tudo isso é gerenciado pelos Controllers do Rails.

Não importa que tipo de lixo o front end envie ou o que ele solicite para recuperar, pois esses elementos protegem o servidor.

Você pode espelhar isso com o comportamento do front end, mas o front end não é o guardião.

Confira alguns dos plugins maiores e você verá exemplos de Serializers e o uso do Guardian.

Obrigado, Robert! Eu precisava desse feedback!

Com certeza vou verificar!

Atenciosamente,

E aí, Robert!

Tenho analisado o código do plugin e a base de código sobre controles de post (ações), para verificar em quais pontos posso agir mais fortemente em termos de segurança.

Conforme analisado! No front-end, existem algumas etapas que verificam se o usuário pode ou não editar o post, como:

  • 1ª etapa: SiteSetting.post_menu_hidden_items
  • 2ª etapa: attrs.canEdit
  • 3ª etapa: editPost() - !post.can_edit - controllers/topic

Mas, mesmo que manipulado no front-end, uma vez enviado ao servidor back-end em posts_controller.rb, dentro do método:

def update

O Rails solicita novamente o post, como uma verificação final:

  • !guardian.public_send(“can_edit?”, post)
  • guardian.ensure_can_edit!(post)
  • PostRevisor

Obrigado pelas suas insights!
Isso é ótimo.

Muito bem. Fico muito feliz que você tenha persistido e ido mais fundo :+1:t2: