A Reflexão é uma desvantagem, pois as variáveis ​​privadas não podem ser restringidas?

O modificador private é usado para restringir o acesso fora da classe, mas usando reflexão outras classes podem acessar métodos e campos privados. Então, eu estou querendo saber como podemos restringir a acessibilidade, se é parte do requisito.

13
Esta não é uma questão específica da linguagem? A reflexão opera de maneira diferente em diferentes idiomas. Eu estou querendo saber se esta pergunta deve ter uma tag para Java ou outra coisa.
adicionado o autor robertc, fonte
Os modificadores de acesso privado existem principalmente para dizer aos programadores "não use isso de fora da classe, e se você realmente fizer isso, não reclame se a próxima versão quebrar seu código" não como um recurso de segurança rigorosamente imposto.
adicionado o autor user8669, fonte
Código de baixa confiança não pode usar reflexão privada (pelo menos não em outras montagens, eu esqueci os detalhes). O código de confiança total pode simplesmente usar ponteiros para ignorar quaisquer restrições no processo.
adicionado o autor user8669, fonte
@WayneConrad: sim, isso é específico do idioma e da versão do idioma. Marquei java e você pode marcar todos com outros idiomas relevantes.
adicionado o autor smci, fonte
dependendo da reflexão da linguagem é relativamente mais caro do que referências diretas também, se o desempenho é uma preocupação. É claro que depende do que você está fazendo (teste ou inicialização do aplicativo vai ficar bem)
adicionado o autor Dahn Jahn, fonte
Se você está falando sobre Java, você pode restringir a reflexão com um gerenciador de segurança e com o próximo isolamento do módulo java 9 (encapsulamento akastrong).
adicionado o autor eckes, fonte
Os usuários também podem corrigir seu código para fazer o que quiserem. Com uma exceção parcial para o DRM (que não é poderoso o suficiente para fornecer proteção duradoura), qualquer pessoa que tenha acesso ao seu aplicativo (binários ou código-fonte) pode fazer qualquer coisa com ele.
adicionado o autor Brian, fonte

6 Respostas

O propósito dos modificadores de acesso é informar aos desenvolvedores que escrevem código sobre qual é a interface pública de uma classe. Eles não são de forma alguma uma medida de segurança e não ocultam ou protegem literalmente qualquer informação.

54
adicionado
@Brian Até que alguém encontre uma vulnerabilidade ou engenharia social que permita contornar as restrições. Não há sentido em tentar usá-las dessa maneira. Esse não é o objetivo principal deles.
adicionado o autor jmibanez, fonte
Isso não é universalmente verdadeiro. Citando C#, o Reflection está disponível apenas para código em execução com confiança total. Isso não se aplica (e não pode) a usuários mal-intencionados do sistema que estão executando o código. No entanto, isso se aplica a plug-ins maliciosos.
adicionado o autor Brian, fonte
@Brian Onde a questão que Brian menciona é relevante é quando um sistema permite que um código de terceiros seja executado sem confiar totalmente nele. Os exemplos incluem caixas de areia do navegador (por exemplo, o applet muito odiado), o mecanismo do Google app e Azure . Seria muito estúpido para o Azure permitir que códigos não confiáveis ​​explorassem os detalhes das principais bibliotecas da plataforma.
adicionado o autor JimmyJames, fonte
@Brian Isso não é 100% correto - existem algumas operações de reflexão que você pode fazer em código parcialmente confiável; simplesmente não permite que você faça coisas como acessar campos privados.
adicionado o autor Luaan, fonte

Para citar Herb Sutter sobre os direitos de acesso às aulas :

"A questão aqui é proteger contra Murphy versus proteger contra Maquiavel ... ou seja, proteger contra o uso indevido acidental (que a linguagem faz muito bem) contra a proteção contra o abuso deliberado (que é efetivamente impossível). No final, se um programador quer mal o suficiente para subverter o sistema, ele vai encontrar uma maneira "

30
adicionado
@ MarkJ. A observação de Herb Sutter é sobre o abuso deliberado pelo desenvolvedor que escreveu a aula em primeiro lugar e talvez seus companheiros de equipe. Eu não acho que haja uma maneira de evitar esse tipo de abuso por recursos de linguagem.
adicionado o autor bcelary, fonte
Proteger contra o abuso deliberado pode ser teoricamente impossível, mas é efetivamente possível, tornando o abuso suficientemente difícil que isso aconteça muito raramente. É importante ser claro sobre isso. Caso contrário, o software não poderá ser usado em situações como dispositivos médicos críticos para a vida.
adicionado o autor tim, fonte
@bolov que stunt é dependente de idioma eu acho. Embora os pré-processadores C/C ++ provavelmente deixassem você escapar disso, qualquer coisa sem eles provavelmente daria um erro "não é possível usar palavras reservadas em um #define".
adicionado o autor Eloy, fonte
são vezes em que você precisa proteger o código não confiável, mas essa é uma tarefa difícil. Proteger contra erros (Murphy) é o caso mais comum.
adicionado o autor Paul Draper, fonte
#define private public (ignorando que na verdade é Undefined Behavior) e voila Eu tenho acesso total de fora para a parte restrita </​​i> de suas classes.
adicionado o autor Shreyas, fonte

Não, esta é realmente uma vantagem importante. Simplesmente porque algum desenvolvedor não considerou que alguém precisaria acessar alguma parte do estado interno, não significa que nenhum caso de uso legítimo apareça. Nesses casos, o uso do Reflection para realizar uma cirurgia em um objeto pode ser um último recurso. Eu tive que usar essa técnica mais de uma vez.

9
adicionado
Em outras palavras, é uma maneira de contornar uma provável API quebrada - seja devido a requisitos incompletos ou implementação incompleta.
adicionado o autor Kuba Ober, fonte

Você restringe ainda mais a acessibilidade, subindo mais um nível: o ambiente de execução.

Nem todas as linguagens têm esse conceito, mas pelo menos com Java você pode usar um gerenciador de segurança que proíbe a disponibilização de campos privados. Você pode instalar manualmente o gerenciador de segurança no tempo de execução ou adicionar uma política de segurança em um arquivo jar que é então selado para impedir a modificação.

More information on doing this in Java: Reflection Security

4
adicionado

No Python, não há modificadores de acesso. A convenção é prefixar por um sublinhado os métodos e variáveis ​​que não devem ser acessados ​​de fora da classe. Isso impede tecnicamente que você acesse esse campo de uma classe de terceiros? De modo nenhum; mas se você fizer isso, estará sozinho e correrá o risco de quebrar alguma coisa, sem ser capaz de culpar a outra classe.

Em C#, existem modificadores de acesso, mas eles ainda são apenas uma convenção - um que é imposto por um compilador, mas ainda é uma convenção. Isso significa que, tecnicamente, ainda é possível acessar e alterar variáveis ​​privadas, seja através do Reflection ou alterando diretamente a memória (como treinadores de jogos fazem). A conseqüência é exatamente a mesma: se as variáveis ​​de sua classe são alteradas através do Reflection de outra classe, ou através de adulteração de memória por outro aplicativo, e isso quebra alguma coisa em sua classe, não é sua culpa.

Observe que isso, obviamente, cria problemas de segurança nos quais um terceiro pode acessar seus dados; algo que leva a variantes criptografadas de um string e estruturas de dados semelhantes. Mas proteger seu código de tal uso é um sistema operacional mais relacionado e restrições de acesso em nível de código , e não tem nada a ver com Reflection per se.

3
adicionado
Observe que, em C#, somente o código totalmente confiável pode refletir membros particulares. Escrever diretamente para processar memória ainda funciona, mas é mais difícil do que no código nativo.
adicionado o autor Luaan, fonte

Qual reflexão você está falando?

Em muitos sistemas de reflexão, contornar o encapsulamento é uma capacidade explícita que seu código precisa obter e não tem por padrão.

Se você está preocupado com o encapsulamento, a solução simples é simplesmente não usar um sistema de reflexão que não o preserve.

3
adicionado