Categorias
Programming Spam

Boas práticas de envio de e-mail

O envio de e-mails de newsletter é algo sensível para os servidores de hospedagem. Ainda que já tenhamos esse tipo de propaganda, ainda é grande o desconhecimento de como realizar o envio de maneira que não sejam identificados como fonte de spam.

O que é spam?

Spam é o termo usado para referir-se aos e-mails não solicitados, que geralmente são enviados para um grande número de pessoas. Quando o conteúdo é exclusivamente comercial, esse tipo de mensagem é chamada de UCE (do inglês Unsolicited Commercial E-mail).

O conceito é simple mesmo. Ainda que seja uma só mensagem, caso ela seja indesejada do destinatário já a caracteriza como spam e quem a recebeu pode reclamar aos órgão de controle de abuso da internet.

Diante da reclamação, o IP do remetente vai para análise e inicia-se uma busca por novas reclamações provenientes de envio de mensagens por aquele IP ou de mensagens iguais enviadas por aquele IP (nesse caso, a caracterização de de spam para envio em massa – bulk mail). Após a caracterização o IP entra no banco de dados desses órgão, que propagam a informação para os servidores de e-mail espalhados na internet, que começam a recusar e-mails que vierem daquele IP, ou seja, qualquer domínio que utilize aquele IP para o envio de mensagens é recusado, ainda que não tenha sido o domínio responsável pelo spam.

Como desenvolvedor, quero prevenir que meus clientes tenham estes problemas. Vou utilizar este espaço, que será sempre atualizado, para divulgar a política de utilização e as práticas corretas do envio delistas de e-mail (as newsletters).

  1. O envio deve ser para um destinatário por vez e não para mais de um endereço ao mesmo tempo;
  2. O envio precisa ser feito com um período entre uma mensagem e outra (de 5 a 10 minutos, por exemplo);
  3. É imprescindível monitorar o retorno dos e-mails inexistentes (ou outros erros) e removê-los da lista de envio;
  4. Dar a opção em todas as mensagens enviadas para que o destinatário possa se descadastrar da lista.
  5. Não iniciar o primeiro contato com o cliente por e-mail, ou seja, o envio do primeiro e-mail, sem prévia autorização do cliente, caracteriza a prática de spam.

Leia também:

Categorias
Ubuntu

Aumente a velocidade do seu sistema aliviado o arquivo de swap

A maioria dos sistemas operacionais são capases de usar um arquivo ou uma partição conhecida como swap ou arquivo de paginação. Grande parte das distribuições Linux instalam uma por padrão. Este arquivo é usado para aumentar a quantidade de RAM disponível escrevendo uma parte dela no seu disco rígido.

Há um problema nisso: discos rígidos são lentos. Não podemos corrigir este problema agora, mas podemos escapar dele. O kernel do Linux oferece a possibilidade de alterar a configuração que controla o quanto o arquivo de swap é usado, chamada swappiness. Se swappiness é alterado para zero, isso significa que a escrita em disco será evitada até o absolutamente necessário (quando esgotar sua memória), enquanto que se swappiness estiver configurada como 100, isso significa que os arquivos serão escritos em disco em todo tempo.

Meu Ubuntu vem por padrão configurado como 60, indicando que o arquivo de swap será usado com bastante frequência se o uso de memória chegar a um pouco menos da metade da RAM. Você pode checar o valor que está em seu sistema executando:

cat /proc/sys/vm/swappiness

Tenho 2GB de RAM e, sendo um bom valor, posso reduzir a escrita no disco rígido e alterar este número para 10 ou 15. O arquivo de swap será usado apenas quando o uso da RAM chegar a 80 ou 90 por cento. Para alterar o valor de swappiness:

sudo /etc/sysctl.conf

Altere (adicione se não existir a linha) no arquivo:

vm.swappiness = 15

Para evitar a necessidade de reiniciar o sistema, execute:

sudo swapoff -a
sudo swapon -a
sudo sysctl -p /etc/sysctl.conf

Adptado da dica do FOSSwire

Categorias
PHP Ubuntu

Validar CPF com php

Uma função utilíssima para cadastros que exigem CPF. Returna true se o CPF for válido e false se inválido.


function valida_cpf($cpf) {
// verifica se e numerico
if(!is_numeric($cpf)) {
return false;
}

// verifica se esta usando a repeticao de um numero
if( ($cpf == '11111111111') || ($cpf == '22222222222') || ($cpf == '33333333333') || ($cpf == '44444444444') || ($cpf == '55555555555') || ($cpf == '66666666666') || ($cpf == '77777777777') || ($cpf == '88888888888') || ($cpf == '99999999999') || ($cpf == '00000000000') ) {
return false;
}

//PEGA O DIGITO VERIFIACADOR
$dv_informado = substr($cpf, 9,2);

for($i=0; $i<=8; $i++) {
$digito[$i] = substr($cpf, $i,1);
}

//CALCULA O VALOR DO 10º DIGITO DE VERIFICAÇÂO
$posicao = 10;
$soma = 0;

for($i=0; $i<=8; $i++) {
$soma = $soma + $digito[$i] * $posicao;
$posicao = $posicao - 1;
}

$digito[9] = $soma % 11;

if($digito[9] < 2) {
$digito[9] = 0;
} else {
$digito[9] = 11 - $digito[9];
}

//CALCULA O VALOR DO 11º DIGITO DE VERIFICAÇÃO
$posicao = 11;
$soma = 0;

for ($i=0; $i<=9; $i++) {
$soma = $soma + $digito[$i] * $posicao;
$posicao = $posicao - 1;
}

$digito[10] = $soma % 11;

if ($digito[10] < 2) {
$digito[10] = 0;
}
else {
$digito[10] = 11 - $digito[10];
}

//VERIFICA SE O DV CALCULADO É IGUAL AO INFORMADO
$dv = $digito[9] * 10 + $digito[10];
if ($dv != $dv_informado) {
return false;
}

return true;
} // function valida_cpf($cpf)

Copie o código aqui.

Código adaptado do iMasters.

Categorias
Internet Technology

Este CSS não é válido

Difícil eu conseguir responder a quem me indagar em quem voto nas próximas eleições, mas não ocorre o mesmo quando me perguntam em que eu não voto. Fica fácil. Já disse que não voto no Dornelles e nem no Crivella.

Nesta absurda tentativa de recriação da CMPF com nome de recurso tecnológico (CSS), vários outros políticos não estão representando minha opinião. Como somos mal representados! Não obstante o peso gigantesto do mamute Carga Tributária querem retornar o que lutamos para enterrar. E isso porque o governo arrecadou 10 bilhões de reais a mais do que o mesmo período inicial do ano passado!

É grande a chance de eu ir às urnas para anular meu voto a todos os cargos. Anote a lista negra dos seus aí também. Os meus daqui do Rio de Janeiro eu já estou guardando.

Parlamentar
UF
Voto
DEM
Abelardo Lupion PR Não
André de Paula PE Não
Antonio Carlos Magalhães Neto BA Não
Ayrton Xerez RJ Não
Carlos Melles MG Não
Claudio Cajado BA Não
Davi Alcolumbre AP Não
Eduardo Sciarra PR Não
Fábio Souto BA Não
Felipe Maia RN Não
Félix Mendonça BA Não
Fernando de Fabinho BA Não
Germano Bonow RS Não
Guilherme Campos SP Não
Jerônimo Reis SE Não
João Bittar MG Não
João Oliveira TO Não
Jorge Khoury BA Não
Jorge Tadeu Mudalen SP Não
Jorginho Maluly SP Não
José Carlos Aleluia BA Não
José Carlos Machado SE Não
Lira Maia PA Não
Luciano Pizzatto PR Não
Luiz Carlos Setim PR Não
Marcio Junqueira RR Não
Marcos Montes MG Não
Mendonça Prado SE Não
Mussa Demes PI Não
Onyx Lorenzoni RS Não
Osório Adriano DF Não
Paulo Bornhausen SC Não
Paulo Magalhães BA Não
Roberto Magalhães PE Não
Rodrigo Maia RJ Não
Rogerio Lisboa RJ Não
Ronaldo Caiado GO Não
Silvinho Peccioli SP Não
Solange Amaral RJ Não
Vitor Penido MG Não
Walter Ihoshi SP Não
Total DEM: 41
PCdoB
Aldo Rebelo SP Sim
Alice Portugal BA Sim
Daniel Almeida BA Sim
Edmilson Valentim RJ Sim
Evandro Milhomen AP Sim
Flávio Dino MA Sim
Jô Moraes MG Sim
Manuela DÁvila RS Sim
Osmar Júnior PI Sim
Perpétua Almeida AC Sim
Renildo Calheiros PE Sim
Vanessa Grazziotin AM Sim
Total PCdoB: 12
PDT
Ademir Camilo MG Sim
Arnaldo Vianna RJ Não
Barbosa Neto PR Não
Brizola Neto RJ Sim
Dagoberto MS Sim
Damião Feliciano PB Sim
Davi Alves Silva Júnior MA Sim
Giovanni Queiroz PA Sim
João Dado SP Sim
Manato ES Não
Marcos Medrado BA Sim
Mário Heringer MG Sim
Miro Teixeira RJ Não
Paulo Pereira da Silva SP Sim
Paulo Rubem Santiago PE Não
Pompeo de Mattos RS Sim
Sérgio Brito BA Sim
Sueli Vidigal ES Não
Vieira da Cunha RS Sim
Wolney Queiroz PE Sim
Total PDT: 20
PHS
Felipe Bornier RJ Sim
Miguel Martini MG Sim
Total PHS: 2
PMDB
Alexandre Santos RJ Sim
Aníbal Gomes CE Sim
Antônio Andrade MG Sim
Antonio Bulhões SP Sim
Átila Lins AM Sim
Carlos Alberto Canuto AL Sim
Carlos Bezerra MT Sim
Celso Maldaner SC Sim
Cezar Schirmer RS Sim
Cristiano Matheus AL Sim
Darcísio Perondi RS Sim
Edgar Moury PE Não
Edio Lopes RR Sim
Edson Ezequiel RJ Sim
Eduardo Cunha RJ Sim
Elcione Barbalho PA Sim
Eliseu Padilha RS Sim
Eunício Oliveira CE Sim
Fátima Pelaes AP Sim
Fernando Diniz MG Sim
Fernando Lopes RJ Sim
Flaviano Melo AC Não
Flávio Bezerra CE Sim
Francisco Rossi SP Não
Gastão Vieira MA Sim
Geraldo Pudim RJ Sim
Geraldo Resende MS Sim
Henrique Eduardo Alves RN Sim
Hermes Parcianello PR Sim
Ibsen Pinheiro RS Sim
Íris de Araújo GO Sim
João Magalhães MG Sim
João Matos SC Sim
Joaquim Beltrão AL Sim
Jurandil Juarez AP Sim
Leandro Vilela GO Sim
Lelo Coimbra ES Não
Leonardo Picciani RJ Não
Luiz Bittencourt GO Sim
Marcelo Almeida PR Sim
Marcelo Castro PI Sim
Marcelo Itagiba RJ Não
Marcelo Melo GO Sim
Maria Lúcia Cardoso MG Sim
Marinha Raupp RO Sim
Mauro Benevides CE Sim
Mauro Lopes MG Sim
Mauro Mariani SC Não
Max Rosenmann PR Não
Mendes Ribeiro Filho RS Sim
Moacir Micheletto PR Sim
Moises Avelino TO Abstenção
Natan Donadon RO Sim
Nelson Bornier RJ Sim
Nelson Trad MS Sim
Odílio Balbinotti PR Sim
Olavo Calheiros AL Sim
Osmar Serraglio PR Sim
Osvaldo Reis TO Sim
Paulo Henrique Lustosa CE Sim
Paulo Piau MG Sim
Pedro Chaves GO Sim
Pedro Novais MA Sim
Professor Setimo MA Sim
Raul Henry PE Não
Rita Camata ES Sim
Saraiva Felipe MG Sim
Solange Almeida RJ Sim
Tadeu Filippelli DF Sim
Valdir Colatto SC Sim
Veloso BA Sim
Vital do Rêgo Filho PB Sim
Waldemir Moka MS Sim
Wilson Braga PB Sim
Wilson Santiago PB Sim
Wladimir Costa PA Sim
Zé Gerardo CE Sim
Zequinha Marinho PA Sim
Total PMDB: 78
PMN
Silvio Costa PE Sim
Total PMN: 1
PP
Afonso Hamm RS Não
Angela Amin SC Não
Antonio Cruz MS Não
Benedito de Lira AL Sim
Celso Russomanno SP Não
Ciro Nogueira PI Sim
Dilceu Sperafico PR Não
Eduardo da Fonte PE Sim
Eliene Lima MT Sim
Eugênio Rabelo CE Sim
George Hilton MG Sim
Gerson Peres PA Não
Gladson Cameli AC Sim
Jair Bolsonaro RJ Não
João Leão BA Sim
João Pizzolatti SC Sim
José Otávio Germano RS Sim
Lázaro Botelho TO Sim
Luis Carlos Heinze RS Não
Luiz Fernando Faria MG Sim
Márcio Reinaldo Moreira MG Sim
Mário Negromonte BA Sim
Nelson Meurer PR Sim
Neudo Campos RR Sim
Pedro Henry MT Sim
Rebecca Garcia AM Não
Renato Molling RS Não
Ricardo Barros PR Sim
Roberto Britto BA Sim
Simão Sessim RJ Sim
Vadão Gomes SP Não
Vilson Covatti RS Sim
Waldir Maranhão MA Sim
Zonta SC Não
Total PP: 34
PPS
Alexandre Silveira MG Não
Augusto Carvalho DF Não
Cezar Silvestri PR Não
Cláudio Magrão SP Não
Fernando Coruja SC Não
Geraldo Thadeu MG Não
Humberto Souto MG Não
Ilderlei Cordeiro AC Não
Leandro Sampaio RJ Não
Moreira Mendes RO Não
Nelson Proença RS Não
Raul Jungmann PE Não
Total PPS: 12
PR
Airton Roveda PR Sim
Aracely de Paula MG Sim
Bilac Pinto MG Não
Chico Abreu GO Sim
Chico da Princesa PR Sim
Clodovil Hernandes SP Não
Dr. Adilson Soares RJ Sim
Giacobo PR Sim
Gorete Pereira CE Não
Homero Pereira MT Não
Inocêncio Oliveira PE Sim
Jaime Martins MG Sim
Jofran Frejat DF Não
José Santana de Vasconcellos MG Sim
Leo Alcântara CE Sim
Lincoln Portela MG Sim
Lucenira Pimentel AP Sim
Luciana Costa SP Não
Luciano Castro RR Sim
Lúcio Vale PA Sim
Marcelo Teixeira CE Sim
Marcio Marinho BA Sim
Maurício Quintella Lessa AL Sim
Maurício Trindade BA Sim
Milton Monti SP Sim
Neilton Mulim RJ Sim
Nelson Goetten SC Sim
Suely RJ Não
Valdemar Costa Neto SP Sim
Vicente Arruda CE Sim
Vicentinho Alves TO Sim
Wellington Fagundes MT Sim
Total PR: 32
PRB
Cleber Verde MA Sim
Léo Vivas RJ Sim
Marcos Antonio PE Sim
Walter Brito Neto PB Sim
Total PRB: 4
PRTB
Juvenil MG Não
Total PRTB: 1
PSB
Ana Arraes PE Sim
Ariosto Holanda CE Sim
Átila Lira PI Sim
B. Sá PI Sim
Beto Albuquerque RS Sim
Ciro Gomes CE Sim
Dr. Ubiali SP Sim
Eduardo Lopes RJ Sim
Fernando Coelho Filho PE Sim
Givaldo Carimbão AL Sim
Júlio Delgado MG Não
Laurez Moreira TO Sim
Lídice da Mata BA Sim
Luiza Erundina SP Não
Manoel Junior PB Sim
Marcelo Serafim AM Sim
Márcio França SP Sim
Maria Helena RR Sim
Mauro Nazif RO Não
Ribamar Alves MA Sim
Rodrigo Rollemberg DF Sim
Sandra Rosado RN Sim
Valadares Filho SE Sim
Valtenir Pereira MT Sim
Total PSB: 24
PSC
Carlos Eduardo Cadoca PE Abstenção
Costa Ferreira MA Sim
Deley RJ Sim
Eduardo Amorim SE Sim
Filipe Pereira RJ Sim
Hugo Leal RJ Sim
Regis de Oliveira SP Não
Takayama PR Sim
Total PSC: 8
PSDB
Affonso Camargo PR Não
Alfredo Kaefer PR Não
Andreia Zito RJ Não
Antonio Carlos Mendes Thame SP Não
Antonio Carlos Pannunzio SP Não
Arnaldo Madeira SP Não
Bonifácio de Andrada MG Não
Bruno Araújo PE Não
Bruno Rodrigues PE Não
Carlos Alberto Leréia GO Não
Claudio Diaz RS Não
Duarte Nogueira SP Não
Edson Aparecido SP Não
Eduardo Barbosa MG Não
Emanuel Fernandes SP Não
Fernando Chucre SP Não
Freire Júnior TO Não
Gervásio Silva SC Não
Gustavo Fruet PR Não
Izalci DF Não
João Almeida BA Não
José Aníbal SP Não
Julio Semeghini SP Não
Jutahy Junior BA Não
Leonardo Vilela GO Não
Lobbe Neto SP Não
Luiz Paulo Vellozo Lucas ES Não
Manoel Salviano CE Não
Narcio Rodrigues MG Não
Nilson Pinto PA Não
Otavio Leite RJ Não
Paulo Abi-Ackel MG Não
Paulo Renato Souza SP Não
Pinto Itamaraty MA Não
Professor Ruy Pauletti RS Não
Rafael Guerra MG Não
Raimundo Gomes de Matos CE Não
Renato Amary SP Não
Ricardo Tripoli SP Não
Roberto Rocha MA Não
Rodrigo de Castro MG Não
Rômulo Gouveia PB Não
Saturnino Masson MT Não
Sebastião Madeira MA Não
Silvio Lopes RJ Não
Silvio Torres SP Não
Vanderlei Macris SP Não
Waldir Neves MS Não
William Woo SP Não
Zenaldo Coutinho PA Não
Total PSDB: 50
PSOL
Chico Alencar RJ Não
Ivan Valente SP Não
Luciana Genro RS Não
Total PSOL: 3
PT
Adão Pretto RS Sim
Angelo Vanhoni PR Sim
Anselmo de Jesus RO Sim
Antônio Carlos Biffi MS Sim
Antonio Carlos Biscaia RJ Sim
Antonio Palocci SP Sim
Arlindo Chinaglia SP Art. 17
Beto Faro PA Sim
Cândido Vaccarezza SP Sim
Carlito Merss SC Sim
Carlos Abicalil MT Sim
Carlos Santana RJ Sim
Carlos Zarattini SP Sim
Cida Diogo RJ Sim
Dalva Figueiredo AP Sim
Décio Lima SC Sim
Devanir Ribeiro SP Sim
Dr. Rosinha PR Sim
Eduardo Valverde RO Sim
Elismar Prado MG Sim
Eudes Xavier CE Sim
Fátima Bezerra RN Sim
Fernando Ferro PE Sim
Fernando Melo AC Sim
Francisco Praciano AM Sim
Gilmar Machado MG Sim
Guilherme Menezes BA Sim
Henrique Afonso AC Sim
Henrique Fontana RS Sim
Iran Barbosa SE Sim
Iriny Lopes ES Sim
Janete Rocha Pietá SP Sim
Jilmar Tatto SP Sim
Jorge Bittar RJ Sim
José Airton Cirilo CE Sim
José Eduardo Cardozo SP Sim
José Genoíno SP Sim
José Guimarães CE Sim
José Mentor SP Sim
Joseph Bandeira BA Sim
Leonardo Monteiro MG Sim
Luiz Bassuma BA Sim
Luiz Couto PB Sim
Luiz Sérgio RJ Sim
Magela DF Sim
Marco Maia RS Sim
Maria do Carmo Lara MG Sim
Maria do Rosário RS Sim
Maurício Rands PE Sim
Miguel Corrêa MG Sim
Nazareno Fonteles PI Sim
Nelson Pellegrino BA Sim
Nilson Mourão AC Sim
Odair Cunha MG Sim
Paulo Pimenta RS Sim
Paulo Rocha PA Sim
Paulo Teixeira SP Sim
Pedro Eugênio PE Sim
Pedro Wilson GO Sim
Pepe Vargas RS Sim
Reginaldo Lopes MG Sim
Sérgio Barradas Carneiro BA Sim
Tarcísio Zimmermann RS Sim
Vander Loubet MS Sim
Vicentinho SP Sim
Vignatti SC Sim
Virgílio Guimarães MG Sim
Walter Pinheiro BA Sim
Zé Geraldo PA Sim
Zezéu Ribeiro BA Sim
Total PT: 70
PTB
Alex Canziani PR Sim
Armando Abílio PB Sim
Armando Monteiro PE Não
Arnaldo Faria de Sá SP Não
Arnon Bezerra CE Sim
Augusto Farias AL Sim
Jovair Arantes GO Sim
Luiz Carlos Busato RS Sim
Nelson Marquezelli SP Sim
Paes Landim PI Sim
Pastor Manoel Ferreira RJ Sim
Paulo Roberto RS Sim
Pedro Fernandes MA Sim
Sérgio Moraes RS Sim
Tatico GO Sim
Total PTB: 15
PTC
Carlos Willian MG Sim
Total PTC: 1
PTdoB
Vinicius Carvalho RJ Sim
Total PTdoB: 1
PV
Antônio Roberto MG Não
Dr. Nechar SP Não
Dr. Talmir SP Não
Edigar Mão Branca BA Não
Fábio Ramalho MG Não
Fernando Gabeira RJ Não
José Fernando Aparecido de Oliveira MG Não
José Paulo Tóffano SP Não
Lindomar Garçon RO Não
Marcelo Ortiz SP Não
Roberto Santiago SP Não
Sarney Filho MA Não
Total PV: 1

Sobre o mesmo:

Categorias
Banco de dados Programming Technology

Aonde você deseja se conectar hoje?

O site ConnectionString vem com uma proposta simples e muito útil: fornecer linhas de conexão. Tem conexão para tudo. Há conexões bancos de dados (SQL Server, Informix, MySQL, Progress, Paradox, Firebird etc), arquivos de dados (Excel, TXT, SQL Lite etc) e também para outros tipos (MS Project, Active Directory, Exchange, DNS etc).

A idéia de ConnectionString é fornecer uma fácil referência para linhas de conexão.

Hoje, existem 213 linhas de conexão no banco de dados coletadas a partir de outros sites da internet, livros, arquivos de ajuda, msdn ou que tenham sido submetidos pelos colegas desenvolvedores de todo o mundo.

Se alguém conhecer algum projeto semelhante para outras linguagens, não deixe de colocar nos comentários, por favor.

Categorias
PHP

Converter formato de data para o formato BR, em uma linha de código só

Vou pedir licença ao Frederico e também palpitar sobre a possibilidade de, em uma linha, converter o formato de data do banco (funciona para o MySQL e outros bancos) para o formato brasileiro em php.

$data = "2008-01-09 14:56:06";
echo date('d/m/Y H:i:s', strtotime($data)); // mostrará 09/01/2008 14:01:06.
echo date('d/m/Y', strtotime($data)); // mostrará 09/01/2008.

Update em 24/01/2023: Podemos utilizar também DateTimeImmutable:

php > $data = "2008-01-09 14:56:06";
php > echo (new \DateTimeImmutable($data))->format('d/m/Y H:i:s');
09/01/2008 14:56:06
php > echo (new \DateTimeImmutable($data))->format('d/m/Y');
09/01/2008

Simples assim. 🙂

Essa solução funciona para datas no formato yyyy-mm-dd hh:mm:ss e yyyy-mm-dd.

Categorias
Linux

Lista brasileira de equipamentos e serviços compatíveis com Linux

Ajude a divulgar a lista brasileira de equipamentos e serviços compatíveis com Linux
...e concorra a MP4 e MP3 players, mochilas Targus, períodos de VoIP grátis e até a ventiladores USB - além de contribuir automaticamente para doações para a Wikipedia e o WordPress! O BR-Linux coletou mais de 12.000 registros de compatibilidade de equipamentos e serviços (webcams, scanners, notebooks, ...) na sua Pesquisa Nacional de Compatibilidade 2007, e agora convida a comunidade a ajudar a divulgar o resultado. Veja as regras da promoção no BR-Linux e ajude a divulgar - quanto mais divulgação, maior será a doação do BR-Linux à Wikipedia e ao WordPress.

Categorias
Segurança

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

Categorias
PHP

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:

code>/^[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('
/code>/^[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();
Categorias
Technology

Blogueiro gosta mesmo é de reclamar

Quanta reclamação! Basta se descontentar com alguma coisa e lá está o texto publicado. É uma quantidade considerável a de textos reclamando de alguma coisa. E... estão certos!

Aonde mais podemos reclamar do ônibus cada vez menor e com assentos que já não cabem nossas pernas (querendo nos forçar a comprar nosso carro cada vez mais rápido)? Aonde podemos reclamar que em nossa rua não há um latão de lixo sequer e o mesmo fica todo espalhado na rua? Aonde podemos reclamar do atendimento de algum posto público? Não preciso me estender mais, senão já começo a reclamar também.

Não tínhamos voz. Só podíamos reclamar no almoço em família, com a vizinha do ônibus, no trabalho. Mas nossos amigo não podem fazer muito por nós. Não tínhamos nenhuma repercussão. Agora tudo mudou. Esse espaço é nosso. Aqui quem manda somos nós e aproveitamos nossa relevância e, finalmente, podemos fazer algum barulho. Podemos aproveitar que estamos aparecendo na primeira página do Google, que estamos sendo entrevistados, que estamos aparecendo na TV.

Tem sido muito bom poder ver nossa reclamação sem idealização política, apenas nossa vivência, nosso cotidiano, o que sofremos e o que pagamos. E ninguém pode calar a nossa voz.

Isso tudo pode ser usado para o desenvolvimento de nossa sociedade, com mais qualidade de vida, com mais respeito e com mais justiça. Seremos ouvidos? Espero muito que sim. Mas estou certo que é uma manifestação (consciente ou não) que pode fazer um mundo melhor.