Segurança no desenvolvimento de sistemas em Java

Pra quem acha que segurança é só colocar um firewall, rodar um anti-virus e boas, precisa ler esse site do sapão. É um compêndio de técnicas de programação em Java (mas a maioria pode ser "portada" para outras linguagens) para melhorar a segurança das aplicações.

As dicas vão desde o básico, aplicável a todo trecho de código, até tópicos específicos sobre identificadores de seção em servidores de aplicação, uso de SSL nas conexões e proteção de arquivos de dados. São dicas simples mas com resultados efetivos para evitar não só falhas na segurança da aplicação, como também erros inesperados nos sistemas.

É interessante pra todo desenvolvedor, e também para os profissionais de segurança da informação, que muitas vezes se distanciam da programação e tratam a segurança apenas do lado da infraestrutura de TI. Além do que, nas palavras dele: vou precisar de colaboradores, então quem estiver disposto pode entrar em contato comigo. Recomendo a todos!

O site é: http://java.sapao.net/

E o post do lançamento oficial: http://blog.sapao.net/2008/08/segurana-em-java.html

CLT x PJ

O Coragi da experilmes perguntou como calcular se valia a pena mudar de um emprego PJ pra um CLT. Como a conta não é fácil, fiz essa planilha ai em baixo, que está aberta pra quem quiser editar em: http://spreadsheets.google.com/ccc?key=pkGIIoRl9u7Dhu_UoUDcfOg

(Atenção: ao editar diretamente no google docs, os dados estarão visíveis para todos, cuidado ao inserir dados confidenciais).

Ou pra quem quiser fazer o download nos formatos:

  • ODS (Open Office/BROffice)
  • XLS (Excell)

A planilha calcula IRPF, INSS, férias e 13o salário automaticamente, ainda calcula o desconto de 20% na base de calculo do IRPF, considerando o desconto da declaração simplificada. Não incluí FGTS pois nem todos consideram isso uma vantagem. Quem baixar as versões XLS e ODS poderá ver como é feito o cálculo.

Manga ou mangá?

Turma da Monica Jovem (Capa edição 1 - ago 2008)

Turma da Monica Jovem (Capa edição 1 - ago 2008)[foot]Foto protegida por direitos autorais, usada sob proteção da lei 9610/1998, art. 46, pp. III e VIII. Não usar fora do contexto deste blog.[/foot]

Caiu na minha mão por acaso e curiosidade[foot]Ok, confesso que comprei, tinha um último na banca e fiquei curioso...[/foot] um exemplar do tão hypeado mangá da Turma da Mônica Jovem. como minha curiosidade me matava, li e resolvi comentar. Não que seja ruim, longe disso. O Maurício de Souza com sua mão de ferro controla muito bem a qualidade do que sai do seu estúdio. Mas decepciona, porque não atende ao hype! Ou pior: de mangá só tem o nome!

Exagero meu. Alguns dos personagens ainda obedecem a estética do mangá, mesmo que de leve. E a cena clássica do garoto tímido sendo espremido nos mamás[foot]©Muriloq[/foot] da menina estava por lá. Os desenhos caricatos estilo boneca de pano e o uso de tracejados nas bochechas pra dar expressão aos personagens também. Mas pra mim isso não basta! Quatro andorinhas só não fazem mangá!

Faltou ambientação, faltou cenário e faltou um roteiro de mangá. Personagens secundários com arte tradicionalmente "Maurício de Souza", cenários simplistas, excesso de diálogos e um roteiro tipicamente turma da Mônica permeiam toda a revistinha[foot]Nesse ponto eu já desisti de chamar de mangá, e gibi é coisa de paulista[/foot].

Bécassine, uma das precursoras das HQs modernas, era uma historinha narrada abaixo de desenhos ilustrativos.

Bécassine, uma das precursoras das HQs modernas, era uma historinha narrada abaixo de desenhos ilustrativos.

Quando eu leio um mangá "de verdade" eu chego no final com um gostinho de quero mais, se não por nada, porque passou rápido: mangá abusa de informação visual, restringindo a informação verbal ao mínimo necessário. A "arte" é o desenho, e não o texto. Já a Turma da Mônica tradicional, no melhor estilo Bécassine, abusa inclusive do recurso do narrador. Gaças a Deus não tinha narrador nessa historinha, mas ainda assim, a história era escrita, com desenhinhos pra ilustrar, e não o contrário.

Faltou dinamismo nos desenhos (claro, só os 4 personagens principais são mangás), faltaram aquelas longas cenas de movimento, onde o fundo congela e o sangue do leitor também.

Como eu disse, não ficou ruim. O Maurício de Souza não ia deixar. Mas não é mangá. É tão e simplesmente Turma da Mônica!

Porque o google erra as contas?

O Joel mandou um mail hoje perguntando:

Tem alguma boa explicação pra 399999999999999-399999999999998 no google retornar 0?
se 399999999999999-399999999999997 é igual a 2 e 399999999999999-399999999999999 é igual a zero (por sinal, como deveria).

Pro que eu respondi, assim por alto:

Erro de precisão. Ele não trabalha com precisão arbitrária (número infinito de dígitos) e converte isso daí pra:

(3,99999999999999 * 10^14)  - (3,99999999999998 * 10^14), e representa esses caras em binário, com, digamos 32 bits. Aí, em binário, a diferença entre esses caras fica na 33a casa, mas a diferença entre 399999999999999 - 399999999999997 fica ainda na 32a (a diferença é o dobro, logo, uma casa antes em binário 🙂 ).

Por isso o primeiro dá errado e o segundo não.

No email eu dei uma resposta até curta, porque não achei que fosse algo tão importante! Mas em pouco tempo a jess me manda no google chat:

5:18 PM jess.listas: Obrigada =)
5:19 PM me: por?
jess.listas: Relevar o grande mistério da humanidade. Me encaminharam um e-mail seu explicando porque o google erra em algumas contas com numeros grandes

Não sabia que a repercussão da minha resposta ia ser tão grande, então resolvi logo escrever um post a respeito. O Problema que acontece com o google chama-se:

Erro de precisão

E pode acontecer com qualquer um... Quer dizer... Com qualquer sistema digital. O lance é o seguinte: Computadores, e sistemas digitais em geral, representam o número usando bits. Cada sistema pode ter seu padrão, mas o número de bits que se reserva pra representar um número é limitado. Já ouviu falar de sistemas de 16, 32 ou 64 bits? Pois então, esses são os tamanhos que são reservados para armazenar um número inteiro. Em geral, se você tenta enfiar[foot]Eu ia dizer xuxar mas quem não é mineiro não ia entender[/foot] um número maior que isso dentro do inteiro, ele simplesmente não aceita e dá erro. Outros sistemas simplesmente ignoram o erro e "comem" um pedaço do número, e você fica com um "restolho" inútil que não te serve pra nada, sem nem mesmo saber disso.

Pra evitar esses problemas, ao invés de usar números inteiros, alguns sistemas usam "números de ponto flutuante", ou "números reais". Ao invés de armazenar 399999999999999 como 399999999999999, armazena-se 399999999999999 como 3,99999999999999 times 10^{14}. As casas depois da vírgula que não couberem dentro do tamanho estipulado são simplesmente descartadas. E é isso que o google faz[foot]Ou pelo menos deve fazer[/foot], e é por isso que vemos esses erros. Pra dar um exemplo prático, vamos usar um sistema com, digamos, 4 bits. Nesse sistema, vamos subtrair alguns números e ver no que dá:

frac{begin{array}{cr} & 19 \ - & 18 end{array}}{begin{array}{cr} = & 1 end{array}}

Bom, 19 em binário é 10011 e 18 é 10010. Ambos tem mais de 4 bits, então eles serão representados como 1,001 times 2^{4} e 1,001 times 2^{4} respectivamente. Mas, veja bem! Ao eliminar os últimos bits, eu eliminei exatamente o que os números tinham de diferente. Agora ao efetuar a subtração tenho:

frac{ begin{array}{cr} & 1,001_{b} times 2^{4} \ - & 1,001_{b} times 2^{4} end{array} }{ begin{array}{cr} = & 0,000_{b} times 2^{4} end{array} }

Aí vem a outra pergunta:

Porque então 399999999999999-399999999999997 deu a resposta certa?

Essa pode parecer mais difícil, mas tem exatamente a mesma explicação. em binário, 2 ocupa uma casa a mais do que 1: 2 em binário se escreve 10 enquanto 1 se escreve apenas 1. Isso quer dizer que, se eu estou "no limite" de casas decimais, o número 2 consegue ficar dentro da minha precisão, enquanto o número 1 já não consegue mais. Com o nosso exemplo, usemos 17 ao invés de 19. Bom, 17 em binário é 10001, e nossa conta com 4 bits fica assim:

frac{ begin{array}{cr} & 1,001_{b} times 2^{4} \ - & 1,000_{b} times 2^{4} end{array} }{ begin{array}{cr} = & 0,001_{b} times 2^{4} end{array} }

Ajustando o expoente temos que 0,001_{b} times 2^{4} = 1_{b} times 2^{1} = 10_{b} , ou seja, 2.

Então, munidos dessa informação, podemos viajar ainda mais e descobrir

Quantos bits o Google usa para representar números reais?

Como vamos fazer isso? simples. Sabemos que 399999999999999-399999999999998 dá erro, enquanto 399999999999999-399999999999997 não dá. Com isso sabemos que 399999999999999 tem exatamente um único bit a mais do que a precisão que o google usa. Basta então descobrirmos quantos bits a representação binária de 399999999999999 usa, e esse será nosso npumero mágico de bits. Então vamos lá. Segundo minha calculadora do linux, 39999999999999910 = 101101011 1100110001 0000011110 1000111111 11111111112. Contando os bits temos 49 bits. Parece um número estranho, afinal eu falei de 16, 32 e 64. De onde veio esse 49?

Bem, em primeiro lugar, o bit mais significativo (i.e. o bit mais a esquerda) não precisa ser armazenado: ele é sempre 1[foot]Já ouviu falar de zero a esquerda? Pois é, não existe zero a esquerda, e como em binário só existe 0 ou 1...[/foot]. Assim, baixamos pra 48. Um número par pelo menos, mas cadê o resto? Bom, a potência que eu representei antes "a parte" precisa ser armazenada em algum lugar. Os bits que faltam pra completar 64 são os bits que eu uso pra armazenar o expoente, ou potência. Assim, 48 bits representam a "mantissa" e os 16 bits restantes representam o expoente[foot]Como esses valores não correspondem ao padrão da IEEE eu suponho que por algum acaso ou mistério da natureza, os números não estão sendo normalizados como deveriam, e por isso usam menos do que os 52 bits do padrão.[/foot].

Conclusão

Não sei bem que conclusão tirar do fato de termos apenas 48 bits. Preciso estudar melhor o padrão IEEE 754 pra entender isso. De qualquer forma, uma conclusão fica latente:

A calculadora do google não usa python!!!

Isso porque, em python os números tem precisão infinita, e essa conta ficaria assim:

>>> print 399999999999999-399999999999998
1

Então, fica a sugestão para os desenvolvedores da calculadora do google: usem python ou alguma biblioteca de precisão arbitrária, para, pelo menos, não confundir os usuários.

Latex, again?

Instalei um plugin de LaTeX no meu wordpress!! Uhu! funciona! Agora posso contar a piada do ricbit:

Um 8 e um e^x andavam tranquilamente por uma rua, quando de repente o 8 se jogou em um beco e se escondeu. O e^x, preocupado, foi atrás dele:

  • O que aconteceu, 8?
  • É que vem vindo ali um operador de derivada. Ele é um desses bullies que vivem me enchendo. Se ele me pega não sobra nada!
  • Pois eu vou atrás dele. Eu sou um e^x e ele não consegue fazer nada comigo.

Então o e^x vai até o operador de derivada e fala com ele:

  • Pare de incomodar o 8! Eu sou um e^x, e você não consegue fazer nada comigo!
  • Muito prazer, e^x. Eu sou o frac{d}{dy}.

(fade out com trilha sonora: http://www.sadtrombone.com/)

Knol, ou uma enxurada de girinadas.

O google lançou o seu complemento/concorrente da wikipédia: knol!

É tudo que um girino pediu a Deus! Nada de fontes, referências, ponto de vista neutro, o escambau aquático! É simplesmente um repositório de conhecimento, QUALQUER UM! Quer lugar melhor pras minhas girinadas? Pois já comecei por lá: escrevi um artiguinho sobre a Lilica Westies, copiei pra lá sem tirar nem por meu tutorial de fractais, e o que eu gastei mais tempo: um artigão, em inglês, introdutório sobre compressão de dados. (Essa foto aí do lado é uma das ilustrações toscas que eu fiz pro artigo 😉 ) Quem animar, dê uma olhada:

quais sao os tipos de rlogios?

A coisa tá sofisticando TANTO que nem preciso olhar as estatisticas de busca! O pessoal deixa as perguntas estranhas DIRETO nos comentários! Pois então vamos lá. Em primeiro lugar vou reescrever a pergunta de forma a torná-la inteligível, e adequá-la às normas do português "correto":

  • Quais são os tipos de relógio?

Ainda falta uma contextualização, afinal "quais são" é muito vago, então mudemos para:

Quais os tipos de relógio existentes?

Pois bem, como sempre, vou escrever duas explicações: Uma girinada e uma com algum embasamento, apesar de ligeiramente enfeitada com o uso de licença poética e de fatos absurdos relatados pela lixopédia lusitana.

Primeira explicação:

De cara, acho que a explicação mais fácil é que existem 2 tipos de relógio: Os que funcionam e os que não! Mas se eu respondesse só isso, vocês, queridos leitores[foot]como se eu tivesse mais de um, pra usar plural![/foot] iriam reclamar! Pois bem, não reclamem, eu vou responder de forma mais completa. de cabeça assim, consigo pensar nos seguintes tipos, não necessariamente excludentes:

  • Relógio de pulso,
  • de bolso,
  • de mesa,
  • de sala,
  • de ponteiro,
  • de gital ;),
  • de pêndulo,
  • de igreja,
  • de parede,
  • de água,
  • de areia,
  • mecânico,
  • hidráulico,
  • eletrônico,
  • atômico,
  • astronômico,
  • cômico,
  • megafônico e
  • afônico.

Mas vamos tentar usar um pouco de história pra levantar os tipos.

No início, era o verbo, e então Deus criou o substantivo, o adjetivo e o adjunto adverbial causal indicativo temporal. Foi aí que ele percebeu que precisaria de uma forma de marcar o tempo.

De início, a contagem de dias e a separação de manhã, tarde e noite já bastavam. Depois ele precisou de uma coisa mais precisa. Aí surgiu o relógio! Dizem que foi de sol, já que os dias quem marcava era o sol. Então temos aqui nosso primeiro tipo:

  • Relógio de sol

Depois disso, descobriram que água pingando de uma torneira mal fechada pinga sempre na mesma velocidade! Dessa magnífica invenção criaram o tampão de ouvido e também a

  • clepsidra, ou o relógio de água!

Em seguida, viram que as velas também queimam em velocidade igual! E criaram os bolos de aniversário, e depois as

  • velas graduadas.

Mas, sabe como é a civilização? máquinas, sempre máquinas! Queriam um

  • relógio MECÂNICO!

Por último, chega o século 20, com seus transistores, diodos e chips semicondutores. Os relógios, claro, não queriam ficar pra trás! Surgiram os

  • relógios eletrônicos.

Mas tirando o Pêndulo de Galileu e o 130, não existia nenhuma maneira precisa de medir o tempo a não ser observando as estrelas por milhares de anos. Por isso os físicos não se deram por rogados, prenderam um gato numa caixa com um contador geiger e fizeram o

  • relógio atômico.

E assim conseguimos classificar nossos relógios por "força motriz", nos 4 elementos naturais da alquimia:

FogoTerraÁguaAr

  • terra: O relógio de sol, que depende do movimento da terra em torno de si mesma, e os mecânicos, que dependem de pêndulos atraídos pela gravidade da terra.
  • fogo: as velas graduadas.
  • agua: as clepsidras.
  • ar: Os relógios eletrônicos que vivem de vento!

E por ultimo os relógios atômicos que funcionam com 50% de terra, 50% de fogo, 50% de água, 50% de ar, 50% de gato e 50% de ursoporcômem.

A wikipédia, por outro lado usa uma classificação mais simples:

Analógicos, digitais e auditivos. Hein? Auditivos? Porque diabos um relógio auditivo não se encaixaria nas duas categorias anteriores? Sei-la, mas a voz da wikipédia é a voz de Deus...

Por outro lado, podemos cair pra segunda explicação, também baseada na história dos relógios:

Segunda teoria

A segunda teoria classifica os relógios de acordo com "onde" eles ficam. Não, não é posição geográfica não, é só o lugar onde eles estão apoiados mesmo. Pesquisas internacionais revelam que os primeiros relógios, os de sol, eram instalados no chão ou em pedestais. Esses são os

  • relógios de chão.

Enquanto as clepsidras eram instaladas em palácios, dentro de salas próprias, em geral dentro de templos construídos só pra isso, por isso são os

  • relógios de templo.

Já os relógios astronômicos eram construídos "no papel" com mapas das estrelas. Estes são os

  • relógios de mapa.

No mundo moderno, dos relógios que conhecemos hoje, os relógios mecânicos dominam. Os primeiros deles, claro, eram os relógios de sino, que serviam apenas pra tocar os sinos das igrejas na hora da missa. Esses são os

  • relógios de sino (duh).

A evolução deles, claro, são os relógios enormes que ficavam nas torres das igrejas, que são conhecidos por

  • relógios de torre

Com a miniaturização, e coma invenção de galileu pelo pêndulo, na igreja de pisa, surgiram os

  • relógios de parede, também conhecidos como relógios do vovô (do inglês "grandfather clock").

Em decorrência de pêndulos cada vez menores, os

  • relógios de mesa

surgiram. E depois deles os

  • relógios de bolso

e os

  • relógios de pulso.

Por fim temos os modernos relógios que não são colocados em lugar nenhum, ou melhor, ficam em salas próprias, ou dentro da cabeça dos computadores. Esses são os relógios atômicos e os relógios virtuais.

Bom, como sempre, classifiquei os relógios de todo jeito, mas as girinadas permeiam os textos. As dicas pra encontrar a verdade estão por aí, quem quiser que ache! Mas o mais fácil mesmo é perguntar pra professora o que que ela quer, porque professor, sabe como é? Faz cada pergunta infundada só pra provar que a versão dele tá certa...

Balanço geral das frases buscadas...

Pois é...

lá fui eu olhar o que tinha dado. Categorizei, de forma manual mesmo, as buscas em grandes grupos (no total foram 27 grupos, mais um "outros" das queries que eu não consegui categorizar). Pra minha surpresa, o "fondue" ganhou disparado da "muler pelada". Acho que o povo prefere o pecado da gula ao pecado da luxúria... (ou será só que pouca gente escreve sobre fondue por isso as buscas caem com mais freqüência no meu site? quem irá saber?). Aí em baixo um grafiquinho resumindo meu trabalho:

Gráfico das buscas que mais cairam no meu site, categorizadas por assunto.

Gostei também de saber que procuram meu blog pra "coisas sérias" como compressão de dados e colocação de padres no google maps. Mas o objetivo mesmo não era esse. Era recolher frases legais sobre as quais postar...

Frases legais

quem sou eu? curriculum

Será que esse daí queria que o currículo dele já estivesse pronto na internet? Ou será que ele nem mesmo sabe quem ele é? vai saber... (mas quem quiser, tem um link pro MEU currículo aqui 😉

mera

Ein??? Mera? Que diabos é isso?

moro de favor meu filho pode me visitar

Será que ele(a) acha mais fácil encontrar essa informação na internet do que perguntando pro dono da casa?

passei concurso banco brasil 57 chama

Parabéns, seja lá o que isso queira dizer.

E ainda essas 4 que eu pretendo blogar a respeito com mais tempo:

cosseno o que serve para o futuro;1
que lingua falam? os indios pataxó;1
foto garrafa vinho mioranza;1
porque a água apaga o fogo e o álcool não;1

A da garrafa de mioranza, vinho da família da Carol, eu já posto duma vez:

Os finos, e

os de garrfão!

Os outros assuntos eu blogarei mais tarde, ou outro dia... ou não.

Mais "buscas" que cairam aqui.

Sacumé, eu tinha resolvido reviver o blog a partir das buscas interessantes que caiam nele. Pra isso eu precisava listar todas as buscas e encontrar as interessantes. Achar as buscas foi fácil: meu provedor fornece o "awstats" para analisar o tráfego no site e ele separa isso pra mim. Mas pegar da interface dele tava ficando chato porque são muitas, eu queria organizar e analisar antes de escolher "as melhores". Por isso resolvi tratar direto o arquivo de log do awstats.

Como tratar o arquivo de logs do awstats pra extrair as frases de busca

O primeiro passo foi escolher o arquivo. O awstats usa arquivos mensais. Escolhi, claro, o mais recente, afinal é só uma brincadeira. Encontrar lá dentro o que eu queria foi fácil:

$ grep -ni BEGIN_SEARCHWORDS awstats072008.girino.org.txt
380:BEGIN_SEARCHWORDS 343

Ou seja, na começa na linha 380 e se estende por mais 343 linhas. Então vamos extrair essas informações daí, certo? Fiz esse scriptzinho aqui pra isso:

$ file=awstats072008.girino.org.txt;
$ grep_result=`grep -ni BEGIN_SEARCHWORDS $file`;
$ begin_pos=`echo $grep_result | awk -F: '{print $1}'`;
$ size=`echo $grep_result | awk '{print $2}'`;
$ head -$1) $file | tail -$2)

Podem ver que as 4 primeiras linhas "apenas" processam o tamanho do arquivo para encontrar o inicio e fim do trecho que eu quero extrair. E só a ultima linha faz o trabalho mesmo. Eu poderia ter feito "na mão" e colocado logo:

$ head -$3) awstats072008.girino.org.txt  | tail -$4)

Mas perdia toda a graça de se brincar com linha de comando 😉

Mas ainda tem um detalhe: esses "dados" estão "codificados" para uso em url (urlencoded, para os íntimos), e precisamos decodificar. Eu até pensei em um script perl ou sed ou awk pra isso, mas pra que? Como dizia o João Cupim, meu professor de marcenaria no COLTEC, cada atividade tem sua ferramenta apropriada, não improvise ferramentas. Pois pra lidar com URLs, quem melhor que PHP? Então o que levaria uma dúzia de linhas e prometeria ficar incompleto em perl/sed/awk, vira isto daqui em PHP:

<?php
$line = fgets(STDIN); // reads one line from STDIN
while ($line) {
    echo urldecode($line);
    $line = fgets(STDIN); // reads one line from STDIN
}
?>

E ainda com a garantia do PHP de que vai funcionar e ter atualizações futuras, etc e tal!

Basta lascar isso aí num arquivo "urldecode.php" e chamar:

$ head -$5) $file | tail -$6) | php urldecode.php

Et voilá! Seu arquivo de log foi processado com sucesso ;).

No próximo post eu falo sobre as buscas que encontrei.

References   [ + ]

1, 5. begin_pos+size+1
2, 6. size+2
3. 380+343+1
4. 343+2