Questão de segurança

Colegas,

Voltando ao tema, como proteger um código java de um aplicativo desktop que será distribuído pela internet?

O projeto a ser desenvolvido basicamente trata da transmissão, para o servidor do fornecedor, de um arquivo criado e validado na máquina do cliente.

A necessidade de segurança reside, por exemplo, na necessidade de se evitar que algum usuário mal intencionado, tendo acesso ao código java, consiga visualizar o endereço (IP) do servidor e faça ataques via internet.
Outra questão é que o aplicativo desktop efetuará validações no arquivo selecionado pelo usuário e permitirá a transmissão ao servidor somente se o arquivo tiver sido validado sem erros.
Caso o código seja facilmente acessível ao usuário (com algum descompilador) a segurança do projeto estará comprometida, já que o usuário poderá alterar as regras de validação, recompilar o programa e transmitir um arquivo “bichado”.

Reparem que a questão não é simplesmente proteger o código por proteger.

Vejam o caso do programa de declaração do imposto de renda pessoa física, da Receita Federal. O usuário somente consegue transmitir sua declaração se esta estiver de acordo com as regras estabelecidas pelo programa (com base na legislação do Imposto de Renda). Imagine que alguém mal intencionado tenha acesso ao código java, altere-o a seu gosto e, com isso, consiga transmitir uma declaração em desconformidade com o que prescreve a legislação.

Tenho pesquisado sobre o assunto, mas ainda não encontrei nada que me convença definitivamente que posso tranquilamente desenvolver o programa em java que, de alguma maneira, a segurança necessária será alcançada.

Um programa feito em Delphi ou C, por exemplo, após compilado e linkeditado (.exe), salvo engano, dificilmente permite uma engenharia reversa (impossível não deve ser, mas deve ser bem dfícil).

A opção por java, em princípio, reside na característica multiplataforma desta, porém, pelo exposto acima, um nível mínimo de segurança precisa ser mantido.

E então, colegas, o que sugerem? Continuar com java ou partir para outra linguagem?

Andredf, um programa compilado, seja em Delphi, C ou qualquer outra coisa, é na verdade convertido para uma linguagem que o computador entenda, e essa linguagem também é entidade pelos humanos, com a ajuda de um bom editor hexa logico. Ou seja, não é garantia de nenhuma proteção, só deixa as coisas mais difíceis. Olha o caso do Windows, um programa enorme e os caras consegue acham nele a parte de validação, consegue alterar, inserir código no meio e validar um windows pirata como sendo original.

Segundo ponto. Descompilar um programa Java para conseguir um endereço de IP? Para que tanto trabalho. Roda o programa no Linux e pergunta para o Linux: “Linux, que ips esse programa esta acessando”. É muito mais facil. E serve para programas compilados. No windows você faz isso também, mas tem que baixar algum software free no baixaqui.

Esse seu problema não é um problema de linguagem, e sim de infra e validação.

Infra porque seu servidor não pode ficar com a pseudo-segurança que ninguém vai achar ele na net. Ligar em servidor no cabo de rede requer varias providencias de proteger ele do mundo exterior.

Validação porque você nunca, mas nunca, deve confiar no client. Seu server sempre tem validar o que recebe. O programa da receita citado, ele pode ser facilmente alterado e gerado um arquivo errado. Mas te garanto que vai ser muito dificil você conseguir enviar para o server, o mesmo vai rejeitar na hora.

Validação no client serve apenas para evitar processamento desnecessário no servidor, só isso, nada além disso.

Falou.

[quote=bruno.fantin]Andredf, um programa compilado, seja em Delphi, C ou qualquer outra coisa, é na verdade convertido para uma linguagem que o computador entenda, e essa linguagem também é entidade pelos humanos, com a ajuda de um bom editor hexa logico. Ou seja, não é garantia de nenhuma proteção, só deixa as coisas mais difíceis. Olha o caso do Windows, um programa enorme e os caras consegue acham nele a parte de validação, consegue alterar, inserir código no meio e validar um windows pirata como sendo original.

Segundo ponto. Descompilar um programa Java para conseguir um endereço de IP? Para que tanto trabalho. Roda o programa no Linux e pergunta para o Linux: “Linux, que ips esse programa esta acessando”. É muito mais facil. E serve para programas compilados. No windows você faz isso também, mas tem que baixar algum software free no baixaqui.

Esse seu problema não é um problema de linguagem, e sim de infra e validação.

Infra porque seu servidor não pode ficar com a pseudo-segurança que ninguém vai achar ele na net. Ligar em servidor no cabo de rede requer varias providencias de proteger ele do mundo exterior.

Validação porque você nunca, mas nunca, deve confiar no client. Seu server sempre tem validar o que recebe. O programa da receita citado, ele pode ser facilmente alterado e gerado um arquivo errado. Mas te garanto que vai ser muito dificil você conseguir enviar para o server, o mesmo vai rejeitar na hora.

Validação no client serve apenas para evitar processamento desnecessário no servidor, só isso, nada além disso.

Falou.[/quote]

Bruno,
Fico enormemente grato pelas suas considerações.
Mas que tal avançarmos um pouco na discussão?

Apesar de possível, convenhamos que um programa .exe é mais difícil de ser entendido (engenharia reversa seria o termo correto?).

Em java, por outro lado, li que é relativamente fácil se chegar aos arquivos .java a partir de arquivos .class.
E fundamentalmente é isso que eu preciso esclarecer.

Quanto ao programa da Receita Federal, o programa não permite que um usuário registre, por exemplo, um CNPJ que desrespeite as regras de formação de CNPJ estabelecidas pela própria Receita Federal (validação do dígito verificador).
Neste caso, ao executar o comando “Verificar pendências”, é exibida a mensagem “Nº de inscrição no CNPJ inválido”.
Se um usuário consegue substituir o código fonte por outro que desconsidere essa regra, sendo-lhe possível informar um CNPJ inválido, duvido muito que o server da Receita Federal rejeite a declaração devido a erro de CNPJ, ou seja, essa verificação e outras são feitas apenas no aplicativo desktop, pois não há como a aplicação servidora verificar, no momento da transmissão se milhares de arquivos transmitidos quase simultaneamente encontram-se corretos quanto a essa e outras regras.

Posso citar outro exemplo, o programa validador SINTEGRA.
É um programa desktop que valida arquivos sintegra a serem transmitidos à Receita.
Esses arquivos podem ser monstruosos, com milhares de linhas.
Cada registro (cada linha) possui vários campos que precisam ser verificados quanto ao formato e conteúdo.
Essa validação pesada ocorre no programa desktop e a transmissão somente é possível se o arquivo tiver sido validado sem erros.
Não há como manter a validação de cada campo em cada registro a cargo da aplicação servidora que os recebe.

Tudo bem que alguma validação é necessária no lado servidor, mas essas validações pesadas não há como.

Essa discussão é muito interessante.

No caso do .class é possível deixá-lo bem embaralhado para que programas de engenharia reversa tenham dificuldades na sua leitura. Os melhores ofuscadores (programas responsável pelo embaralhamento do código) conseguem garantir que o código obtido pela engenharia reversa não seja compilado, obrigando o programador a estudar o código para realizar as alterações necessárias. Garanto que é uma tarefa bem ingrata, mas não é impossível. Como o colega anterior falou, até o windows o pessoal consegue, mas dá trabalho. O máximo que você pode fazer é dificultar a vida do pessoal, de tal forma que nenhum garoto de sete anos consiga descobrir o seu código fonte.

Em relação a validação, é um ponto interessante. Na verdade, você deveria fazer a validação sempre no servidor. A validação no cliente é apenas para fornecer a resposta mais rápida ao cliente.

Existe uma discussão em sistemas de informação, que é a seguinte: você aceitará apenas registros corretos ou aceitará qualquer registro?!?

Caso você aceite apenas registros corretos, pode ser que você deixe de fora da sua amostragem muitos registros com informações uteis, mas incompletos. Por exemplo, vou preencher um cadastro numa empresa, e posso não querer preencher todos os campos, apenas aqueles que “eu ache” essenciais. Quando o formulário for inserido no sistema, o mesmo deveria aceitar ou rejeitá-lo?!?

Até mais!

Ybadoo
http://www.ybadoo.com.br/

[quote=ybadoo]Essa discussão é muito interessante.

No caso do .class é possível deixá-lo bem embaralhado para que programas de engenharia reversa tenham dificuldades na sua leitura. Os melhores ofuscadores (programas responsável pelo embaralhamento do código) conseguem garantir que o código obtido pela engenharia reversa não seja compilado, obrigando o programador a estudar o código para realizar as alterações necessárias. Garanto que é uma tarefa bem ingrata, mas não é impossível. Como o colega anterior falou, até o windows o pessoal consegue, mas dá trabalho. O máximo que você pode fazer é dificultar a vida do pessoal, de tal forma que nenhum garoto de sete anos consiga descobrir o seu código fonte.

Em relação a validação, é um ponto interessante. Na verdade, você deveria fazer a validação sempre no servidor. A validação no cliente é apenas para fornecer a resposta mais rápida ao cliente.

Existe uma discussão em sistemas de informação, que é a seguinte: você aceitará apenas registros corretos ou aceitará qualquer registro?!?

Caso você aceite apenas registros corretos, pode ser que você deixe de fora da sua amostragem muitos registros com informações uteis, mas incompletos. Por exemplo, vou preencher um cadastro numa empresa, e posso não querer preencher todos os campos, apenas aqueles que “eu ache” essenciais. Quando o formulário for inserido no sistema, o mesmo deveria aceitar ou rejeitá-lo?!?

Até mais!

Ybadoo
http://www.ybadoo.com.br/[/quote]

A validação de milhares de arquivos no servidor de forma que o resultado daquela fosse apresentado imediatamente aos milhares de clientes no momento da transmissão de seus arquivos seria o melhor dos mundos, mas isso é inviável (quase impossível). Em muitos casos, é um processo pesado que exige muito processamento. Como falei antes, no exemplo do caso de arquivos sintegra, estes podem ser enormes (em alguns casos, chegando na casa de 1Gb).
Definitivamente, nesses casos, em que se faz extremamente necessário testar cada registro (tamanho e formato), cada campo (formato e conteúdo), a validação tem que ser feita na máquina do cliente, antes da transmissão.
Após a transmissão, a validação ocorre para apenas alguns poucos campos e registros.

andredf, eu aposto qualquer coisa com você que os dois sistemas mencionados a validação é feita no servidor.

Trabalhei muito no ramo de transporte onde tinhamos que enviar arquivos xml gigantes para o sintrega, mas não utilizávamos o aplicativo dele, faziamos o upload diretamente no servidor dele pelo nosso sistema, e qualquer informação errada, ele rejeitava na hora.

No caso da receita, esse é o maior motivo da lentidão. Porque pegar um arquivo salvar em disco e deixar lá para ser analisado meses depois é facil, o site da receita não ficaria lento só por causa disso. É simplesmente o fato de validar todas as informações que causa da lentidão no site.

O que o ybadoo falou sobre “embaralhar” o codigo, também conhecido como ofuscar realmente é uma ajuda. Mas pensa assim, um programa normal, o cara só vai mexer se ele tiver algum interesse muito grande nisso, isso hoje em dia é mais motivo por questões financeiras do que por qualquer outro motivo. Num caso desses, não importa se seja java normal, java ofuscado, Delphi, C e etc, se o cara tiver um “incentivo” ele vai conseguir alterar seu codigo client. Ai somente o seu server pode te ajudar.

Falou.

[quote=bruno.fantin]andredf, eu aposto qualquer coisa com você que os dois sistemas mencionados a validação é feita no servidor.

Trabalhei muito no ramo de transporte onde tinhamos que enviar arquivos xml gigantes para o sintrega, mas não utilizávamos o aplicativo dele, faziamos o upload diretamente no servidor dele pelo nosso sistema, e qualquer informação errada, ele rejeitava na hora.

No caso da receita, esse é o maior motivo da lentidão. Porque pegar um arquivo salvar em disco e deixar lá para ser analisado meses depois é facil, o site da receita não ficaria lento só por causa disso. É simplesmente o fato de validar todas as informações que causa da lentidão no site.

O que o ybadoo falou sobre “embaralhar” o codigo, também conhecido como ofuscar realmente é uma ajuda. Mas pensa assim, um programa normal, o cara só vai mexer se ele tiver algum interesse muito grande nisso, isso hoje em dia é mais motivo por questões financeiras do que por qualquer outro motivo. Num caso desses, não importa se seja java normal, java ofuscado, Delphi, C e etc, se o cara tiver um “incentivo” ele vai conseguir alterar seu codigo client. Ai somente o seu server pode te ajudar.

Falou.[/quote]

Vamos apostar então?

Sugiro que faça o seguinte:
Baixe o validador do Sintegra, crie um arquivo texto com base no que determina a legislação, registre no campo CNPJ da 1ª linha do arquivo (registro 10) e clique no botão validar.

Você também pode fazer outro teste: baixe o validador do SPED.

andredf, vou fazer o teste sim, hoje não porque estou trabalhando. E sinceramente acredito que vai funcionar, é provalvel que seja um campo que não é importante e não é validado.

Mas agora me diga uma coisa? Porque ficar insistindo em fazer a validação no client? Se tanto server e client forem em Java, criar um jar e utiliza nos outros.

Falou.

[quote=bruno.fantin]andredf, vou fazer o teste sim, hoje não porque estou trabalhando. E sinceramente acredito que vai funcionar, é provalvel que seja um campo que não é importante e não é validado.

Mas agora me diga uma coisa? Porque ficar insistindo em fazer a validação no client? Se tanto server e client forem em Java, criar um jar e utiliza nos outros.

Falou.[/quote]

A insistência é por que a aplicação deve ser assim, ou seja, não pode haver sobrecarga no servidor.
Como já falei antes, são milhares de arquivos e muitos de tamanho exagerado.

Então faz em C mesmo ou qualquer linguagem compilada.

Mas fica ciente que a aplicação é vulnerável.

[quote=bruno.fantin]Então faz em C mesmo ou qualquer linguagem compilada.

Mas fica ciente que a aplicação é vulnerável.[/quote]

Não está totalmente fora de cogitação.
O problema é perder a característica multiplataforma que java possui.

Você conhece algum compilador (gratuito) de C que me permita gerar o executável tanto para Windows como para Linux? Acho que já resolveria a questão.

Só não entendi o por quê de a aplicação em C ser vulnerável. Em que aspecto?