Categorias
Desenvolvimento Web Programação Tutoriais

Git + GPG = Assinando suas contribuições

Recentemente o core do PHP passou por uma situação, no mínimo, inusitada: 2 commits foram feitos em nome de personalidades da comunidade. Isso é possível porque quando registramos uma alteração no git através de um commit, ele registra os dados que queremos que sejam registrados, incluindo o usuário e email que você disse ter (git config user.name "Cauan" e git config user.email "cauan@dominio.com"). Veja que você não precisa validar email nem nada.

Aplicações que hospedam projetos em git geralmente pedem pra gente validar o email usado nos commits, assim são capazes de inferir que aquele código enviado é de quem disse ter enviado. Mas é apenas uma associação “lógica”. O commit diz que foi feito por fulana, e a fulana é uma usuária válida aqui no Github/Gitlab, então vou exibir a foto e nome dessa fulana aqui na interface.

Se o git não garante que quem fez uma alteração é quem diz ser, como a gente pode garantir? Assinando nossas mudanças com uma chave criptográfica.

Felizmente o git permite que a gente especifique uma chave privada configurada no GPG e cuida de todo o processo de assinar nossas mudanças. Na outra ponta, nós compartilhamos a chave pública com o Github/Gitlab para que valide o commit assinado e então possam garantir que aquele código foi feito por quem diz ter feito.

O pessoal do PHP preparou um guia bem completo sobre como configurar o GPG e git para que o incidente não se repita. Vou colocar aqui o resumo do resumo para quem tiver alguma dificuldade com inglês, mas se tiver alguma dúvida, pode usar os comentários.

Atenção: todos os comando devem ser executados com seu usuário normal. Quando necessário, o sudo vai estar explicitado.

O símbolo $ não faz parte do comando, é só pra diferenciar o que é um comando e o que é uma saída de comando. Sempre que tiver o $, você pode copiar o que está na frente e executar no seu terminal.

Primeiro, instale o GPG:

SistemaComando(s)
macOS com Homebrewbrew install gpg
Ubuntu, Debian, Mint, Kalisudo apt install gnupg
CentOS, Fedora, RHELsudo yum install gnupg

Se você usa Zsh como shell, você precisa configurar um tty para que funcione corretamente os comandos interativos com o GPG:

$ mkdir "${HOME}"/.gnupg
$ chmod 700 "${HOME}"/.gnupg
$ >> "${HOME}"/.zshrc echo 'GPG_TTY="$(tty)" && export GPG_TTY || echo "Could not determine TTY: $?" >&2'
$ source "${HOME}"/.zshrc

Verificando que a instalação funcionou:

$ gpg --version | head -2
gpg (GnuPG) 2.2.21
libgcrypt 1.8.6
$ gpg-connect-agent /bye && echo 'GPG ok' || echo 'ERROR: GPG not running'
GPG ok
$ [ -r "${GPG_TTY}" ] && echo 'TTY ok' || echo 'ERROR: TTY not found'
TTY ok

Agora vamos gerar sua chave de assinatura GPG. É imprescindível escolher uma senha forte para proteger sua chave:

$ gpg --batch --generate-key <(echo '
Key-Type: RSA
Key-Length: 4096
Expire-Date: 0
Name-Real: Fulana de Tal
Name-Email: fulana@dominio.com.br
')

Precisamos descobrir a versão curta do ID da chave gerada:

$ gpg -K --keyid-format SHORT
sec   rsa4096/02783663 2020-08-26 [SCEA]
      79694216A0DECA5B53E94E96910A1F8402783663
uid         [ultimate] Fulana de Tal <fulana@dominio.com.br>

Repare no resultado do comando anterior a primeira linha. O que vem após rsa4096/ é o ID que nós queremos, nesse exemplo: 02783663.

Vamos deixar esse valor em uma variável de ambiente para facilitar o restante das configurações, basta executar:

$ export GPG_KEYID=02783663

Estamos terminando, precisamos dizer ao git para usar essa chave para assinar nossas alterações no repositório:

$ git config --global --replace user.signingkey "${GPG_KEYID}"
$ git config --global --replace commit.gpgsign true
$ git config --global --replace tag.gpgsign true

Por último, precisamos informar ao Github/Gitlab nossa chave, para que ele possa verificar o autor das mudanças:

$ gpg --armor --export "${GPG_KEYID}" | pbcopy

pbcopy é um comando do macOS para jogar informação na área de transferência (equivalente a um Ctrl+C). Substitua essa parte pelo comando equivalente no seu ambiente se for outro, ou simplesmente retire o trecho | pbcopy e a chave será exibe no terminal, daí basta selecionar e copiar.

Com a chave copiada, acesse suas configurações:

Feito isso, todos os seus novos commits deve ser assinados e se tudo ocorreu bem, aparecerão como verificados nos Git da vida:

Imagem com uma lista de commits contendo o selo "verified" do Github

Atualizado em 13/04/2021: eu segui esses passos do artigo original em um macOS sem o gpg previamente instalado e com o git relativamente atualizado. Caso seu ambiente já tenha gpg ou a versão do git seja muito antiga, verifique a seguinte resposta no StackOverflow. Agradecimento ao Elton Minetto pela dica nos comentários.

Atualizado em 01/05/2021: como alertou nos comentários o Adjamilton, depois da gente atualizar o conteúdo do arquivo .zshrc precisamos recarregar seus valores usando o comando source "${HOME}"/.zshrc para que as mudanças surtam efeito. O trecho já está atualizado.

Categorias
Desenvolvimento Web noticias Programação

25 erros de programação mais graves

Foi divulgado pelo SANS Institute[en] uma lista com os 25 erros de programação que mais causam prejuízos no mundo. Esta lista foi elaborada por especialistas de mais de 30 instituições dos EUA e organizações internacionais de segurança digital.

tradicional erro de segurança
um erro tradicional

A lista foi subdivida em três categorias: “Interação Insegura entre Componentes”, “Risco no Gerenciamento de Recursos” e “Defesa Porosa” – no original: Insecure Interaction Between Components, Risky Resource Management e Porous Defenses.

Há na lista falhas como possibilidade de injeção de códigos, utilização de algorítmos de criptografia defasado e transferência de dados sensíveis sem criptografia.

No artigo original[en] há várias informações sobre os erros e comentários de renomadas empresas de segurança sobre a importância da lista.

Sem dúvida um texto que vale a pena para todo desenvolvedor.

via: IDG NOW!

Categorias
noticias

Atualização do WordPress e novo tema

No último dia 23 de Outubro saiu uma versão com correção de vulnerabilidades do WordPress. Somente hoje consegui fazer a atualização do blog. Mas aproveitei o ensejo e já instalei um novo tema, mais limpo e bonito. Acredito que agora terei novo animo para voltar a escrever (se é que algum dia eu escrevi algo).

Espero que quem vier ao blog goste das mudanças.

Tenho algumas novidades para contar [mode_miguxo](hihihih xP )[/mode_miguxo].
Aguardem.

Categorias
Desenvolvimento Web PHP Programação

Validação de dados em PHP5 – final

Olá a todos,

Continuando e finalizando a sequência de artigos sobre validação ( veja também a parte 1, 2 e 3 ), iremos abordar a união de procedimentos na validação.

Como vimos anteriormente, todo cuidado é pouco, então quanto maior o número de testes que submetermos um dado, maior a chance de ele chegar a nós da forma que esperamos ( sem causar danos a integridade do sistema ).

Vimos que a utilização de ER é essencial, toda vez que soubermos o padrão do valor esperado. Ou seja, se sabemos que um número de telefone é da forma “3333-4444”, e que isso nunca irá mudar, teremos as ER’s como nossa arma mais forte.

Mas existem casos em que não temos idéia do que o usuáiro pode inserir em um campo. Nestes casos, uma ER não tem grande utilidade, e temos de recorrer a outros recursos, como algumas funções do próprio PHP ou MySQL/Postgree para “limpar” as informações, de modo que ela não prejudique o fucionamento do sistema. Algumas destas funções são:

  • strip_tags() , que tenta limpar ( retirar tags HTML e PHP ) e retornar uma string passada como parâmetro.
  • htmlentities() , substitui TODOS os caracteres que possuírem um correspondente html.

Unindo a utilização destas funções, ER ( quando convir, não se esqueça que para se utilizar uma ER temos de ter um padrão esperado ) e cuidado na hora de pegar valores dos arrays superglobais ( $_POST, $_GET, … ), teremos um sistema com uma boa segurança a injeção de códigos por terceiros.

Vamos então fazer uma função ( não farei uma classe pois a idéia é ser bem especifico, podendo a função ser utilizada como um método sem problemas ).

function valida( $valor, $tipo )
{
$erCPF = '/[0-9]{3}\.[0-9]{3}\.[0-9]{3}\-[0-9]{2}/';
$erCEP = '/[0-9]{5}\-[0-9]{3}/';
$erFONE = '/(0((([0-9]{2}){2})|([0-9]{2})))?[0-9]{3,5}\-[0-9]{4}/';
$erEMAIL = '/[[:alnum:]]\@[[:alnum:]]+(\.[[:alnum:]])+/';
$erDATA = '/(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])\/[12][0-9]{3}/';
$erTEXTO = '/([a-z][A-Z])*/';//aceita somente letras
$erALPHANUM = '/[[:alnum:]]*/';//aceita numeros e letras
$erNUM = '/[0-9]*/';//aceita somente numeros
$erALL = '*';//aceita qualquer coisa
$tipo = strtoupper( trim($tipo) );
$padrao = 'er'.$tipo; //faço concatenação do prefixo 'er' com o tipo, para formar o nome da variavel com o padrao correto.
$valor = strip_tags( htmlentities(trim($valor)), '<a><b><i><p>' ); //limpo a variavel com valor, retirando possíveis funções do PHP ou tags HTML que possam ser prejudiciais ao sistema, mas permitindo algumas que podem ser uteis em determinados casos

if( preg_match( $$padrao, $valor ) )
{
echo 'O dado passou pela validação de padrão.<br/>';
//podemos validar melhor alguns dados
switch( $tipo )
{
case 'CPF':
if ( validaCPF( $valor ) )
echo 'O CPF é válido.';
else
{
echo 'O CPF não é valido';
return false;
}
break;
//você pode por um 'case' para cada tipo de dado que quiser validar com alguma formula especifica
default:
echo 'O dado foi validado';
break;
}
return true;
}
else
echo 'O dado não passou pela validação de padrão.<br/>';

return false;
}

Bom, este é um exemplo de função que poderíamos utilizar para validação de dados, podendo ser inserida em uma classe com um método dela.

Mas como utilizamos ela? Simples, veja( supondo que temos vindo de um formulário um campo email, via POST:

if( valida( $_POST['email'], 'email' ) )
echo 'Email válido';
else
echo 'Email inválido';

Fica fácil não?

Bom, nesta função, é chamada outra função ( validaCPF ), que não é de minha autoria, e que dei os devidos créditos na parte 3 desta série. Esta função implementa o algoritmo de validação do CPF, com seu digito verificador e tudo mais. É um algoritmo muito difundido, e bem documentado na internet, faça uma busca se estiver interessado no assunto. É interessante.

Função para validação de dado( veja o fonte )

É isso, espero ter ajudado, qualquer coisa, mail-me.

Até a próxima.

Categorias
Desenvolvimento Web PHP Programação

Validação de dados em PHP5 – Parte 3

Depois de um longo período sem nada útil, vamos continuar a série mais querida deste blog: “Validação de dados em PHP5”.

Está é a parte 3 da série, e talvez a última ( a menos que surjam pedidos ou dúvidas ) da série, se você não viu, veja: parte 1, parte 2.

Como falei na parte 2, o PHP trabalha com dois padrões de ER ( Expressões Regulares ): o padrão PCRE e o padrão POSIX. Adotaremos de agora em diante o padrão PCRE por ser recomendado pelo próprio manual do PHP.

Na última parte fizemos a validação de um número de CEP.

Agora veremos outros casos de uso, primeiro dois casos simples como o do CEP, um para validar um número de telefone ( possivelmente de celular ) e outro para validar um endereço de email – este último muito útil e utilizado, pois permite uma alta confiabilidade nos dados verificados.

Nossa ER para validar um telefone:

$telER = ‘/(\([0-9]{2}\)\ )?[0-9]{4}\-[0-9]{4}/’; //formato: (67) 9999-0000

Simples não é? Que tal “complicar” um pouco mais? Então compliquemos:

//formato: 0556733334444 ou 06733334444 ou 3333-4444

$telER = '/(0((([0-9]{2}){2})|([0-9]{2})))?[0-9]{3,5}[0-9]{4}/';

E como validar uma data? Fácil fácil…

//formato: 01/01/1001

$dataER = '/(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])\/[12][0-9]{3}/';

Validar um CNPJ:

//formato: 11.222.333/0001-01

$cnpjER = '/[0-9]{2}\.[0-9]{3}\.[0-9]{3}\/[0-9]{4}\-[0-9]{2}/';

Depois que a gente começa, não da vontade de parar, mas parem mesmo assim. Agora que já viram alguns exemplos de ER, tentem fazer a de vocês mesmos. Façam uma ER para validar uma idade ( considerem que existe gente com mais de 100 anos ).

Depois de você ter feito suas ER, pode continuar…

Vamos validar um endereço de email agora:

//formato: nome@host.com ou nome@subhost.host.com

$emailER = '/[[:alnum:]]\@[[:alnum:]]+(\.[[:alnum:]])+/';

Será que já ta bom?

Não, mas chega de mostrar ER pronta para vocês, ta, uma última vez, fiz um arquivo de teste explicando algumas ER: Expressões Regulares . Espero que seja útil.

Lembrem-se que estou utilizando o padrão PCRE, então nada de usar estas expressões com as funções “ereg”.

Enquanto escrevia esta parte, pensei em algumas coisas para continuação. Então, ainda esta semana concluo.

Até.

ps.: para quem ver o arquivo e ficar curioso sobre a verificação extra do CPF, saiba que é utilizado o Algoritmo de Validação do CPF ( procure por este termo no Google ) implementado em PHP pelo Jefferson Estanislau da Silva e disponibilizado no link: http://www.vivaolinux.com.br/scripts/verScript.php?codigo=401. Fiz algumas alterações, pois no original, usava ER no padrão POSIX. Darei mais detalhes na continuação.

Categorias
Desenvolvimento Web PHP Programação

Validação de dados em PHP5 – Parte 2

Continuando a série de artigos sobre validação de dados ( veja a primeira parte ) com PHP5.

Nota: usarei “cliente” para me referir a um usuário do sistema, ou mesmo outro sistema que interaja conosco. Usarei também ER para designar expressão regular, que é o assunto base deste post.

Anteriormente, havíamos abordado uma validação mais geral, onde tínhamos de aceitar vários tipos de dados.

Agora, vamos abordar uma situação onde esperamos um dado específico vindo do cliente – usarei “cliente” para referir tanto ao usuário do sistema quanto outros sistemas – por exemplo, em um campo de formulário, onde esperamos um nome ou um email.

Um dos recursos mais eficientes em se tratando de validação é o uso de expressões regulares. E é com isto que iremos trabalhar.

Vamos a uma definição:

“Uma expressão regular, na Informática, define um padrão a ser usado para procurar ou substituir palavras ou grupos de palavras. É um meio preciso de se fazer buscas de determinadas porções de texto.” Fonte: Wikipédia.

Então uma expressão regular é um padrão. Por isso não podemos utilizar uma expressão regular para validar algo que desconhecemos, porque seria muito difícil ou mesmo impossível encontrar um padrão para tudo.

Não pretendo explicar os fundamentos de uma expressão regular, se desejar alguma referência, recomendo o site: http://guia-er.sourceforge.net

Como podemos utilizar uma expressão regular para validar um campo de um formulário? Precisamos de uma função do PHP que faça esta verificação para a gente, uma função que compare nossa expressão regular com o valor a ser testado.

O PHP oferece algumas funções para isso, vejamos duas delas:

 

ereg( string $expressão , string $variável [, array $registros ] )

 

Retorna TRUE se $variável “bater” com $expressão, e FALSE se a expressão não casar ou se acontecer algum erro. referência

//nossa ER, um padrão para CEP
$cepER = ‘^[0-9]{5}\-[0-9]{3}$’;
//vamos supor que temos a variável $_POST[‘cep’] vinda de um formulário

//fazemos então a verificação
if( ereg( $cepER, $_POST[‘cep’] ) )
echo “Isso parece um CEP válido”;
else
echo “Isso não é um CEP válido”;

Por que não podemos afirmar se o CEP está correto? Simplesmente porque com a ER analisamos apenas a forma da variável, ou seja, se ela tem o mesmo número de caracteres, se são do mesmo tipo e estão nas mesmas posições. Para afirmarmos com segurança que o CEP é válido, teríamos de verificar se o valor está cadastrado nos Correios ou em alguma outra fonte segura. Mas isso foge ao nosso escopo.

Essa função ereg permite fazer a buscar por um padrão em uma string utilizando padrão POSIX, mas o PHP fornece outra função para a mesma tarefa, com desempenho melhor, e baseado no padrão PCRE ( compatível com PERL ). Esta função é a preg_match.

preg_match( string $expressão , string $variável [, array &$matches [, int $flags [, int $offset ]]] )

Retorna 1 se a $variável “bater” com a $expressão, e 0 caso contrário. referência.

Vamos ver o uso do preg_match na mesma situação do exemplo anterior:

//nossa ER, um padrão para CEP
$cepER = ‘/[0-9]{5}\-[0-9]{3}/’;

//vamos supor que temos a variável $_POST[‘cep’] vinda de um formulário
//fazemos então a verificação, poderíamos omitir o “== 1”, já que o PHP converte 0 e 1 para false e true respectivamente
if( preg_match ( $cepER, $_POST[‘cep’] ) == 1 )
echo “Isso parece um CEP válido”;
else
echo “Isso não é um CEP válido”;

Notem a diferença na nossa ER. Mudamos os caracteres de inicio e final, isto acontece por conta da diferença entre os padrões que as funções utilizam.

O artigo já está muito grande, continuarei a falar sobre ER nos próximos artigos. Vamos ver como criar ER para validar telefone, email e por último CPF ( que incluiremos outro teste de validação além da ER ).

Uma última dica, utilizem ER juntamente com o método do artigo anterior, para aumentar a segurança de seu sistema ( pense em outras formas para isso também ).

Por enquanto é só.

Não esqueçam de validar tudo.

Categorias
PHP Programação

Validação de dados em PHP5 – Parte 1

Olá a todos, nesta série de artigos ( espero eu ) estarei dando algumas dicas de como tratar valores com o PHP.

Uma preocupação cada vez maior ao se criar sistemas é a segurança, e um das áreas em que devemos ter maior preocupação é na hora de usar informações provenientes de agentes externos ( pessoas ou outros sistemas ).

Temos de levar sempre em consideração que nunca poderemos prever todas as maneiras que um usuário ( ou mesmo outro sistema ) utiliza nosso código. Os usuários sempre arrumam uma forma “inovadora” de usar nossos sistemas, podendo causar falhas críticas no mesmo. Então, sempre que for criar um sistema que interaja com alguém, proteja-se de todas as maneiras possíveis, e dependa o mínimo possível de fatores externos ( como boa vontade e conhecimento do usuário, ou que o sistema alheio não falhe ).

A palavra de ordem é: “Valide TUDO”. Sim, qualquer coisa que venha de fora de seu sistema tem de passar por validação. Seja um valor utilizado para atribuição à variável, seja para uma consulta à um banco de dados, tudo deve ser validado.

Nesta primeira parte, falarei sobre o tratamento de variáveis vindas do cliente ( usuário ou sistema ) pelos arrays superglobais $_POST e $_GET, e que não sabemos ao certo o que esperar ( ou seja, podemos utilizar este método para receber um nome, telefone, email, data ou qualquer outro dado suportado pelo PHP ).

Abaixo segue um método que utilizo para tratar estes valores:

public function __set( &$atributo, $valor )
{
//Testa se existe algum valor a ser utilizado na atribuição
if( !empty($valor) )
{
//Faz a conversão de tipo, como o PHP tem uma tipação fraca ( ou seja, deixa você atribuir uma String em um váriavel que tinha um Número ), isto pode ajudar.
settype( $valor, gettype($atributo) );

//Verifico se magic_quotes_gpc está ativo na configuração do PHP, isto será removido no PHP 6( veja sobre isto )
if (!get_magic_quotes_gpc())
//Adiciono caracter de scape em tudo o que possa ser perigoso ( veja mais sobre isso )
$valor = addslashes($valor);
//Faço a atribuição normalmente.
$atributo = $valor;
}
}

Este é um método que pode ser incluído em qualquer classe. Ele possui um nome especial “__set”, que para o PHP, indica que ele será usado toda vez que for feita uma atribuição de valor para um atributo da classe ( posso falar mais sobre os métodos especiais do PHP5 em um próximo post ).

Por exemplo, quando utilizarmos o comando abaixo, atribuindo o valor nome do array $_GET ao atributo nome de nossa classe:

$classe->nome = $_GET[‘nome’];

O PHP interpretará como:

$classe->__set( nome, $_GET[‘nome’] );

 

e fará todas as verificações que contém no método.

Podemos utilizar outras funções de validação em nosso método, mas temos de tomar cuidado para não restringir demais os dados, lembrando sempre que esta validação será usada TODA vez que fizermos uma atribuição.

Poderíamos por exemplo refinar nossa validação utilizando expressões regulares, mas isso provavelmente não lhe traria bons resultados, pois uma expressão regular define uma regra que deve ser seguida, e no nosso caso, nós não sabemos o que esperar, então como poderia impor uma regra? Perderíamos muitos dados corretos utilizando uma expressão regular ( a menos que ela fosse pouco restritiva, o que faria perder sua função ).

 

Por enquanto é isto.

Espero ter ajudado, e até a próxima.