Em Java, o private
modificador de acesso é considerado seguro, pois não é visível fora da classe. Então, o mundo exterior também não conhece esse método.
Mas eu pensei que a reflexão Java pode ser usada para quebrar essa regra. Considere o seguinte caso:
public class ProtectedPrivacy{
private String getInfo(){
return "confidential";
}
}
Agora de outra aula vou obter informações:
public class BreakPrivacy{
public static void main(String[] args) throws Exception {
ProtectedPrivacy protectedPrivacy = new ProtectedPrivacy();
Method method = protectedPrivacy.getClass().getDeclaredMethod("getInfo", null);
method.setAccessible(true);
Object result = method.invoke(protectedPrivacy);
System.out.println(result.toString());
}
}
Neste momento eu apenas pensei que o método privado ainda era seguro, pois para fazer algo como acima, devemos saber o nome do método. Mas se a classe contém método privado escrito por outra pessoa, não temos visibilidade deles.
Mas meu ponto se tornou inválido por estar abaixo da linha de código.
Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods();
Agora, isso method[]
contém todas as coisas que você precisa fazer acima. Minha pergunta é: há uma maneira de evitar esse tipo de coisa usando o reflexo Java?
Estou citando algum ponto da documentação Java para esclarecer minha dúvida.
Dicas para escolher um nível de acesso:
Se outros programadores usam sua classe, você deseja garantir que erros de uso indevido não aconteçam. Os níveis de acesso podem ajudá-lo a fazer isso. Use o nível de acesso mais restritivo que faça sentido para um determinado membro. Use privado, a menos que você tenha um bom motivo para não o fazer.
fonte
getDeclaredMethods
retornaria nomes que parecem lixo.Respostas:
Depende do que você entende por "seguro". Se você estiver trabalhando com um gerenciador de segurança que permite esse tipo de coisa, então sim, você pode fazer todos os tipos de coisas desagradáveis com reflexão. Mas nesse tipo de ambiente, a biblioteca provavelmente pode ser modificada para tornar o método público de qualquer maneira.
O controle de acesso é efetivamente "consultivo" em um ambiente como esse - você está efetivamente confiando que o código funcionará bem. Se você não confia no código que está executando, deve usar um gerenciador de segurança mais restritivo.
fonte
check*
chamadas relevantes , basicamente.Os modificadores de acesso não têm nada a ver com segurança. Na verdade, você pode e deve considerar os modificadores de acesso como o reverso da segurança - não é para proteger seus dados ou algoritmos, é para proteger as pessoas da necessidade de saber sobre seus dados e algoritmos. É por isso que o modificador padrão é pacote - se eles estão trabalhando no pacote, provavelmente já precisam saber.
Junto com o conhecimento dos dados e dos métodos de seu código, vem a responsabilidade de saber quando e como usá-lo. Você não coloca private em seu método inIt para evitar que alguém descubra sobre ele, você faz isso porque (a) eles não vão saber que você só chama isso depois de foo e somente se bar = 3,1415 e (b) porque não adianta nada saber disso.
Modificadores de acesso pode ser resumido em uma frase simples "TMI, cara, eu então não precisa saber disso."
fonte
Ao dizer 'seguro', você está protegendo você ou outros desenvolvedores, que estão usando sua API para não danificar o objeto chamando seu método privado. Mas se você ou eles realmente precisarem chamar esse método, eles podem fazer isso com o Reflection.
fonte
A questão é de quem você está tentando salvá- lo. Em minha opinião, esse cliente de seu código é o que perde aqui.
Qualquer código (escrito por você ou outros) que tenta acessar um
private
membro da classe acima está essencialmente cavando sua própria cova.private
os membros não fazem parte da API pública e estão sujeitos a alterações sem aviso prévio. Se por acaso um cliente consumir um de tais membros privados da maneira dada acima, ele irá falhar se for atualizado para uma versão mais recente da API na qual o membro privado foi modificado.fonte
Com facilidade, vem a responsabilidade. Existem coisas que você não pode fazer e coisas que você pode fazer, mas não deve fazer.
O modificador privado é fornecido / usado como / da maneira mais restrita. Membros que não deveriam ser visíveis fora da classe devem ser definidos como privados. Mas isso pode ser quebrado com a Reflexão como vemos. Mas isso não significa que você não deva usar private - ou eles não são seguros. É sobre você usar as coisas de forma criteriosa ou construtiva (como reflexão).
fonte
Supondo que você confie no programador cliente de sua API, outra maneira de ver é o quão 'seguro' é para eles usarem essas funções específicas.
Suas funções publicamente disponíveis devem fornecer uma interface clara, bem documentada e que raramente muda em seu código. Suas funções privadas podem ser consideradas um detalhe de implementação e podem mudar com o tempo, portanto, não são seguras para uso direto.
Se um programador cliente se esforça para contornar essas abstrações, ele está de certa forma declarando que sabe o que está fazendo. Mais importante, eles entendem que não há suporte e podem parar de funcionar com versões futuras de seu código.
fonte
private
não é para segurança, é para manter o código limpo e evitar erros. Ele permite aos usuários modularizar o código (e como ele é desenvolvido) sem ter que se preocupar com todos os detalhes dos outros módulosDepois de liberar seu código, as pessoas podem descobrir como ele funciona. Não há como "ocultar" a lógica se você quiser que o código seja executado em um computador. Mesmo a compilação para binário é apenas um nível de ofuscação.
Portanto, não há como configurar sua API para fazer coisas especiais que você não deseja que outras pessoas possam chamar. No caso de uma API da web, você pode colocar os métodos que deseja controlar no lado do servidor.
fonte