Tropeçando 20

Activate Remote Desktop REMOTELY!!! | commandlinefu.com

Site lista fatos (sic) sobre Richard Stallman

“Depois dos fatos sobre Chuck Norris, sobre Zé Mayer e, mais recentemente, sobre Sonia Abrão, eu descobri acidentalmente um site que lista os Fatos sobre Richard Stallman. Segundo a página, a idéia surgiu depois de o bom doutor ter dito que ele usava o wget para navegar na Internet usando um daemon para enviar-lhe as páginas por e-mail.”

PHP é à quinta-feira – 50 dicas sobre desempenho e segurança | Peopleware

Howto access ext3 partition from Windows | Ubuntu Geek

This tutorial will allow you to access your ext3 partition under Windows, using Sun VirtualBox and Ubuntu.
The tutorial is pretty long due to the images, but they explain things easier sometimes (they are not just meaningless screenshots) (forgive me for your scroll button 😛 )

Upload Pie – The Simple Image Sharing Tool

Compartilhamento de arquivos com data de vencimento

Mantis Bug Tracker

Gerenciamento de erros

TIOBE Software: Tiobe Index

Índice de relevância das linguagens na internet. As linguagens mais discutidas atualmente.

SSH sem senha

Usar SSH para conectar a um computador remoto é conveniente, mas há algumas desvantagens. Uma delas é que você precisa digitar a senha a cada vez que você conecta, o que é incômodo num terminal interativo mas inaceitável em um script, pois você precisa que a senha esteja no script. O outro é que uma senha pode ser quebrada. Uma senha longa, aleatório e complexa ajuda, mas torna as autenticações interativas ainda mais incovenientes. É mais seguro ativar o SSH para funcionar sem senhas de uma vez. Primeiro, você precisa ativar um par de chaves para o SSH usando ssh-keygen como este para gerar chaves RSA (mude o argumento para dsa em chaves DSA).

ssh-keygen -t rsa

Serão criados dois arquivos em ~/.ssh, id_rsa (ou id_dsa) com sua chave privada e id_rsa.pub com a sua chave pública. Copie a chave pública para o computador remoto e adicione-a na lista de chaves autorizadas com

cat id_rsa.pub >>~/.ssh/authorized_keys

Agora você pode sair da sessão SSH e iniciá-la novamente. Você não será solicitado a entrar com senha, embora se relacionar uma frase-senha para a chave você será solicitado a digitá-la. Repita isso para cada usuário e cada computador remoto. Você pode fazer isto de maneira ainda mais segura ao adicionar

PasswordAuthentication no

a /etc/ssh/sshd_config. O SSH passará a recusar todas as conexões sem uma chave, tornando a quebra de senhas impossível.

Tropeçando 19

Scripturae Publicações

Encoding from AVI to MPEG format | commandlinefu.com

O mistério da porta 25: por que provedores bloqueiam o acesso?

Ikea Job Interview » CrisDias weblog

Usando o nome da rede wifi para mandar recados para os vizinhos » CrisDias weblog

E Se a Veja Fosse Publicada no Universo Star Wars? « Eu Podia Tá Matando

Color Scheme Designer 3

Esquema de cores com código HTML

Ninite Easy PC Setup – Download/Install Multiple Programs Fast

Faça um pacote dos seus programas mais usados para instalar facilmente em uma nova máquina.

Ketarin – keep your setup packages up to date

Instalação de programas a granel. É permitido até mesmo instalação offline.

Marc Fleury, fundador do JBoss, critica a campanha de Monty Widenius para “salvar” o MySQL

Monty Widenius, cuja empresa vendeu o MySQL para a Sun, há algumas semanas vem travando uma longa e ruidosa batalha para tentar convencer entidades regulatórias a de alguma forma impedir que a Oracle adquira o MySQL junto no momento em que se concretize a aquisição da Sun por ela.

Microsoft reconhece bug do Windows que existe há 17 anos | Gizmodo Brasil

sso que é procrastinação! Ou melhor, ignorância sobre uma falha básica do próprio sistema operacional por quase duas décadas: um engenheiro do Google descobriu recentemente uma vulnerabilidade no kernel 32-bit do Windows — vulnerabilidade que existe desde 1993.

[Lifehacker] Teste de velocidade de navegadores: os resultados Windows 7 | Gizmodo Brasil

Teste com Chrome, Firefox 3.6 e Firefox 3.5.4

OpenShot 1.0: editor de vídeo em código aberto

Por que proxy não transparente é melhor que o transparente | lucianopinheiro.net

A explicação simples é a de que, além de ser mais seguro, o proxy não transparente usa o recurso do cache de DNS. Para a explicação detalhada, leia o post:

Taxista e o trânsito

Pelo menos aqui no Rio de Janeiro, os taxistas, que teoricamente são os profissionais do trânsito, são, notadamente, os piores motoristas. Algumas pessoas até falam mal dos motoristas de ônibus, mas, em minha concepção, os taxistas estão muito à frente quando se fala em dirigir mal e perigosamente.

Durante A Grande Família de ontem me diverti numa cena que é completamente real: Agostinho (Pedro Cardoso) está muito apreensivo para o exame de renovação da carteira de habilitação. Marilda (Andréa Beltrão) ajuda-o revendo as questões da prova e pergunta:

– O que você deve fazer quando está na pista da esquerda e vem um motorista em maior velocidade?
– Essa é mole. Eu não preciso fazer nada.
– Se você não precisasse fazer nada não seria uma questão do exame, né, Agostinho? Você tem que dar passagem ao invés de ficar se arrastando na pista da esquerda.

Taí o pensamento dos taxistas. Claro que estou generalizando, mas difícil mesmo é algum agir de maneira diferente da do Agostinho.

Outro dia, voltando de madrugada para casa, eu estava numa rua principal de Piedade quando um taxista abruptamente avançou o sinal de uma das ruas laterais para entrar nesta rua principal, inclusive avançando na pista contrária (a rua é de mão dupla). Eu estava um pouco distante, mas com uma boa velocidade porque os sinais estavam todos abertos para mim. Se eu não estivesse atento, certamente bateríamos. Diminuí um pouco a velocidade e fiz questão de buzinar com vontade desde o momento em que o vi avançando o sinal até o momento em que eu o ultrapassei. Ao parar no próximo sinal, ele parou ao meu lado e teve a cara de pau de querer tentar dizer alguma coisa. Eu me antecipei:

– Você é doido? Poderia causar um acidente numa pista a essa hora da noite com a pista livre e os sinais abertos para mim.
– Eu sei que estou errado, mas não tem necessidade de buzinar.
– Você tá errado e não tem direito de falar nada.

Só para não deixar o Agostinho mentir, a atitude do taxista demonstrou que ele ficou incomodado com minha buzina e não com o perigo que corremos pela imprudência dele. Às favas com a direção defensiva.

Vergonhoso.

Tropeçando 10

The Web Application Security Consortium / The Web Security Glossary

The Web Security Glossary is an alphabetical index of terms and terminology relating to web application security. The purpose of the Glossary is to clarify the language used within the community.

Texas Stadium Fail « FAIL Blog: Pictures and Videos of Owned, Pwnd and Fail Moments

E o windows…

Gráfico da produtividade moderna » CrisDias weblog

The Novel 100: The 100 Greatest Novels of All Time

Os 100 livros que moldaram a história mundial

Playing For Change | Peace Through Music

Paz através da música. “Taí uma iniciativa não-racial com muitos negros”.

Blog do Márcio d’Ávila » Portal da Vivo comprometido prolifera fraude

Ontem, foi descoberto um incidente de segurança que comprometeu o portal da operadora de telefonia Vivo e pode ter afetado milhares de usuários.

Tropeçando 7

PHP é à quinta-feira – Gerar uma password | Peopleware

Color Hunter

crie e encontre paleta de cores a partir de imagens

Sua Língua » Arquivo » Não compre o novo VOLP! — 1ª parte

Blank/erase a DVD-RW | commandlinefu.com

Apagando um DVD-RW na linha de comando

Se eu soubesse que web 2.0 era isso… » CrisDias weblog

nth-child | Boas práticas de Desenvolvimento com Padrões Web

50 Creative and Inspiring 404 Pages | Webdesigner Depot

Gmail divulga boas práticas para listas, newsletters e mailings não serem interpretadas como spam

9 Interesting Facts To Know About a Website | Tools

Na internet, quando todos forem supers ninguém será super » CrisDias weblog

Os top cinco erros não técnicos cometidos por desenvolvedores | Pacote201.com.br

Tropeçando – I

Tropeçando por aí:

Browsershots

What is Browsershots?

Browsershots tests your website’s compatability on different browsers by taking screenshots of your web pages rendered by real browsers on different operating systems.

Reinstalando o GRUB

Alguém tentou reinstalar o outro Sistema Inoperacional e ele, genialmente, apagou a MBR e, conseqüentemente, a opção de escolha do GRUB? Agora dá para recuperar. Pelo Ubuntu (distribuição que uso e o do exemplo), é claro.

Ferramentas de segurança de rede

100 ferramentas de segurança e controle da rede.

Google não ajuda a descobrir senhas de blogs

A Juliana Barreto, da Info, divulgou que o Google ajuda a descobrir senhas de blogs, especificamente o WordPress. Outros meios de comunicação também divulgaram, mas mencionei a Info por ser um canal de renome quanto as informações de tecnologia (embora o MeioBit já tenha se tornado o canal mais influente e correto em minha opinião).

Tudo não passou de uma notícia divulgada apressadamente, sem uma apuração cuidadosa do fato. Levo em conta que uma jornalista que esteja trabalhando na Info conheça algo de tecnologia, ou pelo menos sabe onde procurar informações que dêem embasamento às suas informações e notícias. Tivemos, infelizmente, uma disseminação da insegurança àqueles que utilizam o wordpress.

O Élcio, preocupado com a falta de segurança noticiada, resolveu apurar e o resultado é muito diferente do divulgado. Convido-os a visitar o Blog Fecha Tag para ver o que ele escreveu (e também convido-os a acompanhar, pois há conteúdo de primeira qualidade). De qualquer forma, peço licença a ele para copiar aqui:

Para começar, leia o trecho a seguir desta notícia na INFO Online:

Mas, quando tentou o Google, o especialista descobriu que serviço de publicação de blogs WordPress é vulnerável a pesquisas específicas. O site armazena dados como hashes MD5, que podem conter senhas, de uma maneira visível ao buscador. Bastaria informar um trecho do algoritmo para encontrar dados relacionados ao usuário e suas senhas.

Uau, belo trabalho jornalístico esse hein? Espalhando o medo. Imagine a reação de um leigo, que tenha um um blog WordPress, ao ler essa pérola da desinformação. Não parece, lendo esse texto, que o WordPress tem uma seríssima falha de segurança que pode ser explorada usando o Google? Que se alguém “informa um trecho do algoritmo” vai descobrir uma porção de dados seus? Bom, fui ao site do sujeito e li o artigo em que ele explica como quebrou a senha.

O que aconteceu é que o WordPress do tal Murdoch foi invadido por um cracker, que criou uma conta de usuário. O WordPress guarda suas senhas em um formato chamado MD5, um formato de criptografia que transforma qualquer senha num hexadecimal de 32 caracteres, assim:

  • “Sylar” = 7bef5e9683a92c37a266283bf229c2e8
  • “Cap. Nascimento” = 40a4b69d3132bd562dc03e2de30fda3e
  • “Pat Morita” = 261f3880c4eab23075356dbc6b5befc3

O WordPress faz isso para proteger você. Se alguém invadir seu blog, mesmo assim não vai descobrir sua senha. Então o Murdoch não tinha a senha do sujeito que invadiu o blog dele, tinha apenas o texto “20f1aeb7819d7858684c898d1e98c1bb”. O jeito comum de se descobrir essa senha é o chamado ataque de dicionário. Você consegue um enorme dicionário de palavras e nomes comuns, e faz um programa que converte cada um deles para MD5. Se, ao converter algum, você encontrar o tal texto “20f1…”, pronto, você descobriu qual é a senha.

O problema é que esses ataques levam tempo, pois o computador tem que processar milhões de palavras. E se a senha não for uma palavra comum do dicionário, ela não vai ser encontrada. Assim, “banana” vai ser encontrada, mas “Xbanana43” não. Acontece que palavras muito, muito comuns, como “banana”, ou nomes de pessoas, provavelmente já tem seu hash MD5 publicados em alguma página na web. E, se está publicado, o Google encontra. Por exemplo, procure pelo MD5 de banana.

Então, ao procurar o MD5 da senha do invasor, o Murdoch achou páginas como essa aqui, uma lista de pessoas chamadas “Anthony”. Ele resolveu tentar então “Anthony” como senha, e funcionou.

Perceba que isso não torna o WordPress mais vulnerável, porque a senha ia ser descoberta de qualquer maneira, só ia levar um pouco mais de tempo. E para fazer isso, o sujeito tem que ter acesso ao banco de dados com as senhas. Ou seja, já tem que ter invadido o sistema.

Foi só isso. Não há nenhuma vulnerabilidade no WordPress que, se alguém vai ao Google e “informa um trecho do algoritmo”, vai descobrir seu CPF e número de cartão de crédito. Aliás, será que esse repórter sabe o que significa “algoritmo”? Aprendi quando era criança, quando minha mãe ouviu meu primeiro palavrão, que gente não devia usar palavras que a gente não sabe o que significa.

Você que usa WordPress, não precisa se desesperar. Só não use senhas óbvias, não acredite em tudo o que você lê por aí e não entre em pânico.

Videos da Campanha Antispam.br

A CGI.br trabalhando por uma internet mais fácil. Excelentes vídeos, vale a pena assistir sejam profissionais ou leigos.

Estão disponíveis 2 vídeos da Campanha Antispam.br:

   * Navegar é Preciso — trata do funcionamento da Internet, com suas vantagens, riscos e necessidade de proteção;
   * Os invasores — apresenta os tipos de códigos maliciosos, seus efeitos e como eles podem entrar no computador do usuário.

Eles podem poder obtidos para download na seguinte URL:

* Vídeos Antispam.br
http://www.antispam.br/videos/

Os vídeos estão disponíveis na área de downloads do site Antispam.br e podem ser baixados em diferentes formatos, permitindo a sua visualização em diversos sistemas operacionais. Estes vídeos também possuem diferentes tamanhos e resoluções para download via conexão discada ou banda larga.

Outros dois vídeos serão divulgados futuramente: “Spam”, aborda os tipos de spam existentes, suas diferenças e malefícios, incluindo códigos maliciosos e fraudes; e “A Defesa”, cujo enfoque é o aspecto comportamental, enfatizando como usuário pode evitar a maioria das ameaças.

Atenciosamente,

CERT.br
https://listas.cert.br/mailman/listinfo/certbr-anuncios

Segurança no PHP

Os 6 requisitos mínimos

por Er Galvão Abbott (http://www.galvao.eti.br/) na revista PHPMagazine (http://www.phpmagazine.org.br/)

logo-phpmagazine

Apresentareremos neste artigo 6 requisitos que todo o desenvolvedor PHP deveria contemplar em sua aplicação. São boas práticas e hábitos simples que implementam um nível mínimo de segurança em qualquer sistema ou ferramenta desenvolvida com a linguagem.

A linguagem PHP é, sem dúvida, uma das mais populares quando o assunto é desenvolvimento de aplicações web. Existe, porém, um preconceito muito grande com a linguagem quando a questão é segurança. Neste artigo veremos 6 requisitos básicos que toda aplicação deveria possuir e que implementarão o mínimo de segurança em tudo o que você desenvolver.

Conceito: PHP é uma linguagem mais vulnerável do que as outras?

Atualmente impera no mercado de desenvolvimento um preconceito relacionado à segurança de aplicações PHP. A linguagem é freqüentemente alvo de duras críticas por parte da própria comunidade de desenvolvimento, e não é raro presenciarmos aplicações extremamente vulneráveis que, com toda a certeza, dão razão a essas críticas.

Este preconceito, totalmente equivocado, tem suas origens na extrema flexibilidade de configuração e uso da linguagem e no número cada vez maior de desenvolvedores inexperientes que começam sua carreira desenvolvendo aplicações PHP, ignorando questões básicas, seja por falta de conhecimento ou porque estão procurando agilizar sua produção pessoal.

Este artigo não é destinado apenas aos que estão começando. É surpreendente o número de desenvolvedores mais experientes que, por terem adquirido vícios, ainda ignoram as questões que apresentaremos aqui.

Requisito #1: Esqueça register_globals!

Register_globals é, sem dúvida alguma, a diretiva de configuração mais popular e polêmica já implementada no PHP. É popular entre os desenvolvedores por tornar o processo de programação muito mais ágil e prático. É polêmica porque retira tanto do programador quanto do interpretador da linguagem a responsabilidade em definir a origem das informações utilizadas pela aplicação.

Esta diretiva causou tantos problemas que começou a vir desabilitada por default a partir da versão 4.2.0 e será eliminada na versão 6. Por isso, se você ainda programa com register_globals ligada, está mais do que na hora de mudar.

Observe o seguinte exemplo de código:

$url = "http://www.meusite.com.br/index.php";
$errMsg = "Usuário%20não%20autenticado";
if (!$autenticado) {
header("Location: $url?erro=$errMsg");
} else {
/* A aplicação age com se o usuário estivesse autenticado */
}

Este código verifica por uma variável booleana chamada $autenticado, que tipicamente viria de uma sessão aberta quando o usuário se autenticou em nossa aplicação ou mesmo de um cookie. Ao utilizarmos os recursos da register_globals, porém, não estamos dizendo ao interpretador PHP que este dado deve vir obrigatoriamente de uma destas duas fontes.

Sendo assim, o interpretador procurará por esta variável em diversas fontes (variável do servidore web, dados de formulário, cookie, arquivos enviados por upload, query string ou sessões) das quais ele obteve informações até encontrá-la, desprezando se esta fonte está correta.

Torna-se extremamente simples “enganar” a sua aplicação PHP, basta que eu chame o seu arquivo passando a variável esperada por query string.

http://www.meusite.com.br/script.php?autenticado=1

Ao receber a query string contendo a informação “autenticado”, este dado será automaticamente interpretado como uma variável pelo interpretador, quer exista sessões ou cookies ou não.

Uma dúvida freqüente é “se não tenho autorização para desligar a register_globals o que eu posso fazer?”. A resposta para isso é tão simples quanto tudo o mais na linguagem: programe como se ela estivesse desligada! Veja como fica o nosso código ao não utilizar a register_globals:

$url = "http://www.meusite.com.br/index.php";
$errMsg = "Usuário%20não%20autenticado";
if (!$_SESSSION['autenticado']) {
header("Location: $url?erro=$errMsg");
} else {
/* A aplicação age com se o usuário estivesse autenticado */
}

Observe a mudança: ao utilizarmos o array super global $_SESSION, estamos explicitando para o interpretador que a informação “autenticado” tem que, obrigatoriamente, vir de uma sessão. Isto significa que será impossível para o interpretador confundir este dado com um dado enviado pela query string, pois este fica armazenado em um array super global diferente:

  • $_SERVER – Informações definidas pelo servidor web (Apache, IIS etc)
  • $_GET – Informações passadas por query string ou por um formulário web utilizando o método GET
  • $_POST – Informações enviadas, tipicamente, por um formulário web utilizando o método POST
  • $_COOKIE – Informações fornecidas por um cookie HTTP
  • $_FILES – Informações fornecidas por arquivos que foram enviados via upload HTTP
  • $_ENV – Informações fornecidas pelo ambiente do servidor
  • $_REQUEST* – Informações fornecidas por GET, POST ou COOKIE

* Cuidado: O uso do array super global $_REQUEST é quase tão perigoso quanto a register_globals em si, pois nesse caso a informação pode vir de qualquer um dos 3 métodos: GET, POST ou COOKIE.

Requisito #2: Use require e não include

O comando include e seus derivados – como include_once – são freqüentemente usados em detrimento do comando require. Este fato curioso a princípio é conseqüência da similaridade do comando include com outras linguagens, como C e Java.

O que muita gente não sabe, porém, é que este comando carrega consigo um risco muito grande para sua aplicação: se por algum motivo a inclusão do arquivo falhar – erro de digitação, disco corrompido etc – será gerado um erro de nível warning, um nível leve de erro que não causa a parada da execução do script.

Utilizando o comando require, garantimos que, no caso de falha na carga do arquivo, seja gerado, além do erro de nível warning, um erro de nível fatal. Em bom português isso significa que a execução do seu script será imediatamente interrompida neste caso. Por que é bom que seu script seja interrompido no caso de falha de inclusão de outro arquivo? Simples: no caso de falhas, as variáveis, as funções, as constantes e o que mais este arquivo carregava consigo, simplesmente, não estarão disponíveis.

Requisito #3: Filtre a entrada de dados!

Um dos principais conceitos de segurança é a filtragem dos dados que são recebidos antes de utilizá-los. A falta de fitlragem é a causa de inúmeros problemas de segurança, incluindo o infame SQL Injection, ou Injeção de SQL. Observe o seguinte código:

require_once("conecta.php");
$conn = conecta();
$sql = "SELECT email FROM usuarios WHERE usuario_id = " . $_GET['uid'];
$recordSet = mysql_query($sql);
while ($record = mysql_fetch_assoc($recordSet)) {
echo $record['email'] . '<br />';
}
mysql_close();

O problema deste código é utilizar um dado informado pela query string (uid) sem fazer nenhuma filtragem, ou seja, nosso script aceitará cegamente qualquer coisa que for digitada como valor de uid. Observe a seguinte URL:

http://www.meusite.com.br/script.php?uid=198%20OR%20’x’=’x’

Após a conversão dos caracteres especiais desta URL, o valor de uid será (sem aspas duplas): “198 or ‘x’=’x'”. Note que, quando concatenarmos isto à nossa query, ela terá sofrido uma grande modificação:

SELECT email FROM usuarios WHERE usuario_id = 198 or 'x'='x'

É por isso que a chamamos de “Injeção de SQL”. A parte em vermelho acima é formada de SQL válido, mas completamente alienígena à nossa plicação: ele modifica o comportamento original da query.

Observe que, com um mínimo de esforço, um usuário conseguiu expor todos os e-mails cadastrados em nossa base de dados: como foi utilizado o operador “OR” e a segunda condição (‘x’=’x’) é sempre verdadeira, serão exibidos todos os registros.

Para evitarmos este tipo de problema, devemos aplicar um tratamento à informação antes de utilizá-la. Caso a minha query – como neste exemplo – esteja esperando um número inteiro, a solução é simples: forçamos a conversão do dado recebido para número inteiro:

require_once("conecta.php");
$conn = conecta();

settype($_GET['uid'], integer);

$sql = "SELECT email FROM usuarios WHERE usuario_id = " . $_GET['uid'];
$recordSet = mysql_query($sql);
while ($record = mysql_fetch_assoc($recordSet)) {
echo $record['email'] . '<br />';
}
mysql_close();

A partir de agora, qualquer dado enviado pela query string será primeiro convertido para inteiro e somente depois desta conversão é que o utilizaremos. No caso de uma tentativa de Injeção de SQL, nosso script considerará apenas a parte numérica (198), como deveria ser. Além disso, se por um acaso nosso script receber apenas texto, a função settype converterá isto para o número 0.

Caso a minha query esteja esperando uma string a solução reside em criar um tratamento que valide esta string. Vejamos um exemplo: possuo uma query que busca dados de um usuário através de seu endereço de e-mail:

$sql = "SELECT nome, sobrenome FROM usuarios WHERE email = '" . $_GET['email'] . "'";

Sabemos que um endereço de e-mail é formado por um nome de usuário, uma arroba e um domínio. Para fins de simplificação do exemplo, trabalharemos como se o usuário só pudesse usar letras, números e o caracterese de ponto – para quem levar a validação de e-mail a sério consulte a RFC 822. Podemos representar isso através de uma expressão regular:

/^[A-Z|a-z|0-9|\.|]+\@[A-Z|a-z|0-9\.|]+/

Sendo assim, só aceitaremos o dado de endereço de e-mail se ele estiver dentro dos padrões de minha expressão regular. Nosso código então ficaria assim:

require_once("conecta.php");
if (preg_match('
/^[A-Z|a-z|0-9|\.|]+\@[A-Z|a-z|0-9\.|]+/', $_GET['email'])) {
$conn = conecta();

$sql = "SELECT nome, sobrenome FROM usuarios WHERE email = '" . $_GET['email'] . "'";
$recordSet = mysql_query($sql);
while ($record = mysql_fetch_assoc($recordSet)) {
echo $record['email'] . '<br />';
}
} else {
die("O dado informado não é um endereço de e-mail válido.");
}
mysql_close();