Archive for novembro \22\-02:00 2010

PHP Conference Brasil 2010

Posted on novembro 22, 2010. Filed under: PHP |

Boas novas. Essa semana acontecerá o PHP Conference Brasil 2010 na Unifieo em Osasco, 25/26 e 27 de Novembro. Estarei participando do evento e apresentando duas palestras:

* Novas Funcionalidades no PHP 5.3 – Sexta-feira, dia 26/11 – 12hrs às 13hrs
* Segurança Web com PHP 5 – Sábado, dia 27/11 – 12hrs às 13hrs

Com certeza é o principal evento esperado pela comunidade PHP durante o ano. Teremos assuntos muito interessantes. Será um troca de experiências única, portanto não falte! Para se inscrever agora somente na hora do evento, mais informações acesse:

http://www.phpconf.com.br

Ler Post Completo | Make a Comment ( None so far )

PHP Patterns parte 7: ActiveRecord

Posted on novembro 22, 2010. Filed under: PHP |

O design pattern ActiveRecord é uma abordagem para acessar dados em um banco de dados. Normalmente uma tabela do banco de dados é mapeado em um objeto. Um único objeto representa um registro dessa tabela. O objeto instanciado disponibiliza métodos de acesso e propriedades para insert/update/delete/select e mapea cada coluna da tabela que esta sendo trabalhada.

Abaixo são alguns projetos PHP que implementam o pattern ActiveRecord:

Doctrine
Php Active Record
Propel
Adodb

Abaixo vamos exemplificar a utilização do pattern ActiveRecord baseado na biblioteca do Adodb.

Inserindo dados na tabela:
class usuario extends ADOdb_Active_Record{}
$usuario = new usuario();
$usuario->nome = 'João';
$usuario->sobrenome = 'Silva';
$usuario->save();

O código acima irá gerar:
INSERT INTO usuario (nome, sobrenome) VALUES('João', 'Silva');

Após o INSERT, o campo “id” do objeto é populado com o id gerado pelo INSERT. Utilizar a função save() após o insert, os dados do registros serão atualizados com UPDATE. Outras formas de update são setar um valor para o campo “id” do objeto usuario ou realizar um save após ter feito um load da tabela. Exemplo:

// efetuar um insert
$usuario->sobrenome = 'Silva de Almeida';
$usuario->save();

// fazer um load e depois save gera um update
$usuario->load("id=1");
$usuario->sobrenome = 'Silva de Almeida';
$usuario->save();

O código gerado será:
UPDATE usuario SET sobrenome='Silva de Almeida' WHERE id=1;

Para carregar um registro da tabela do banco de dados em um objeto ActiveRecord:
$usuario->load("id=10");
echo $usuario->nome;

O SQL gerado será:
SELECT * FROM usuario WHERE id=10

Quando quiser retornar várias linhas de uma tabela utilize o método Find. Ele irá retornar um array de objetos do tipo Usuario:
$usuario = new usuario();
$usuarioArray = $usuario->Find("nome like ?", array('Am%'));

O SQL gerado será:
SELECT * FROM usuario WHERE nome like 'Am%'

Relacionamento Um para Muitos: No relacionamento um para muitos temos que especificar as tabelas que irão se relacionar. Vamos usar as tabelas “usuario” e “permissao”. O join vai ser realizado entre os campos usuario.id e permissao.usuario_id. Primeiro vamos carregar um registro da tabela de usuário e seus respectivos registros da tabela de permissao. A tabela de permissao guarda informção sobre os privilégios que o usuário tem no sistema. Um usuário pode ter diversos privilégios. Por exemplo, permissão para gerar relatório, permissão para acessar área administrativa, etc.. Após obter os privilégios do usuário, vamos modificar a descrição de cada registro de permissão individualmente:

class usuario extends ADOdb_Active_Record{}
ADODB_Active_Record::ClassHasMany('usuario', 'permissao','usuario_id');
$usuario = new usuario();
$usuario->Load("id=1");
foreach($usuario->permissao as $p) {
  echo $p->descr_permissao;
  $p->descr_permissao .= " (Modificado)'';
  $p->save(); // registros de permissao deverão ser salvos individualmente
}

Existem outras sintaxes de implementação do pattern ActiveRecord, porém a idéia será sempre a mesma. Você pode checar nos links que citei acima para maiores detalhes.

Ler Post Completo | Make a Comment ( 2 so far )

Segurança no PHP: Email Injection

Posted on novembro 16, 2010. Filed under: PHP |

Como a maioria de nós sabemos, o php nos fornece a função “mail()” para o envio de emails programados. A utilização da função “mail()” é simples e muito útil em determinadas situações. Podemos especificar parâmetros como assunto, e-mail de destino, corpo da mensagem e os headers. Um ponto importante que devemos levar em consideração relacionado com a segurança de nossa aplicação é quando usamos dados de usuários para configurar algum desses parâmetros de envio de e-mail, principalmente ainda, quando usamos esses dados para montar o header de nosso e-mail.
É muito comum ter na maioria dos sites uma página contendo um formulário de contato. Muitas vezes deixamos na mão do usuário o preenchimento do e-mail de origem, pois é a forma mais usada e também mais correta. Porém se não tratarmos corretamente essa informação no lado do servidor, possibilitaremos algum usuário malicioso explorar um ataque conhecido como Email Injection. A falha permite que o usuário malicioso envie emails spam sem seu consentimento.

Explorando

Vamos supor que você utilize o script abaixo para envio de email:

<?php
$email_origem = $_POST['email'];
mail( "nome-destino@exemplo.com.br", "Contato via form", $message, "From: $email_origem" );

Perceba que a variável “$email_origem” é obtida através de um formulário enviado via POST. Como não fazemos nenhum tratamento, possibilitamos um usuário malicioso injetar um código que irá enviar spam para outros usuários. Imagine o usuário enviando o seguinte código no campo de formulário do email de origem:

email1@exemplo.com.br
CC: email2@exemplo.com.br, email3@exemplo.com.br, email4@exemplo.com.br

Dessa forma, o usuário esta manipulando nosso campo header. Ao final do e-mail de origem, é inserido uma quebra de linha (\r\n) seguida de um campo de cópia (CC), fazendo com que o e-mail seja copiado para outros endereços.

Prevenindo

A prevenção contra a injeção no header de e-mail é simples: Ou você faz o tratamento, removendo os caracteres de nova linha da string, ou faz uma função de validação que checa a existência desses caractéres na string obtida via POST.

Tratando:
$email_origem = preg_replace( "/[\r\n]/", '', $email_origem);

Validando:
if (preg_match( "/[\r\n]/", $email_origem) ) {
[... redireciona o usuário para uma página de erro e sai da aplicação ...]
}

Caso você esteja usando o Zend_Mail (Zend Framework) ou PEAR Mail, fique tranquilo, pois essas libs já fazem o tratamento devido contra email injection.

Ler Post Completo | Make a Comment ( 1 so far )

PHP Patterns parte 6: Decorator

Posted on novembro 10, 2010. Filed under: PHP |

Uma classe que implementa o pattern “Decorator” permite adicionar funcionalidades em outra classe existente sem que haja necessidade de alterá-la, através de métodos intermediários. Decorator é uma forma flexível alternativa a utilização de “herança” de classe. Em determinadas situações o decorator ajuda a evitar uma explosão de “sub-classes” deixando o código mais simples e fácil de se manter. Geralmente a classe “Decorator” recebe uma referência de um objeto e cria métodos que servirão para “decorar” este objeto. Um exemplo do pattern decorator pode ser encontrado no Zend Framework, mais especificamente na classe Zend_Form. O Pattern Decorator serve como uma luva ao se trabalhar na criação de elementos de formulários HTML.

Para exemplificar a utilização do pattern Decorator vamos criar uma classe chamada “Texto” que possui um método que retorna uma string que foi passada como parâmetro no construtor.

<?php
class Texto {
  protected $texto;

  public function __construct($texto)
  {
    $this->texto = $texto;
  }

  public function obtemTexto()
  {
    return $this->texto;
  }
}

Em seguida vamos criar nossas classes “Decorator”. A classe decorator, chamada “TextoAspasDecorator”, irá receber o objeto da classe “Texto” no construtor. Portanto, no decorator, temos disponível o método “exibeTexto()” que irá retornar a string armazenada no objeto “Texto” formatada com aspas duplas no início e no fim. Detalhe que podemos observar aqui é que estamos deixando o objeto original intacto.

<?php
class TextoAspasDecorator {
  protected $obj_texto;

  public function __construct(Texto $obj_texto)
  {
    $this->obj_texto = $obj_texto;
  }

  public function exibeTexto()
  {
    return '"' . $this->obj_texto->obtemTexto() . '"';
  }
}

Criei mais um exemplo de decorator abaixo. O nome da classe é “TextoExclamacaoDecorator”. Ela possui a mesma estrutura do exemplo anterior, a única diferença é que a formatação da string ao invés de usar aspas duplas esta usando exclamação “!”

<?php
class TextoExclamacaoDecorator {
  protected $obj_texto;

  public function __construct(Texto $obj_texto)
  {
    $this->obj_texto = $obj_texto;
  }

  public function exibeTexto()
  {
    return '!' . $this->obj_texto->obtemTexto() . '!';
  }
}

Vamos para à utilização das classes criadas acima. Veja como é simples a utilização de nossos decorators:

// instância da classe Texto
$texto = new Texto("Mensagem Exemplo");

// Instânciando as classes Decorators e
// passando o objeto $texto para o construtor
$decorator_aspas = new TextoAspasDecorator($texto);
$decorator_exclamacao = new TextoExclamacaoDecorator($texto);

// printando o texto original
echo $texto->obtemTexto() . PHP_EOL;

// Printando os textos formatados pelos decorators
echo $decorator_aspas->exibeTexto() . PHP_EOL;
echo $decorator_exclamacao->exibeTexto();

Resultado:
Mensagem Exemplo
"Mensagem Exemplo"
!Mensagem Exemplo!

O Zend Framework faz a utilização deste pattern na renderização dos elementos de formulário usando Zend_Form. É claro que a implementação no Zend Framework é diferente da nossa, eu usei exemplos bem simples para facilitar o entendimento, porém existem diversas outras maneiras de implementar este pattern.
Nos forms do Zend Framework é possível definir com quais tags os elementos e labels de formulários serão envolvidos. Você também pode definir se serão exibidos mensagens de erro e de descrição na renderização do formulário, entre outras. Para maiores detalhes acesse: ZF Elementos de Formulário.

Ler Post Completo | Make a Comment ( None so far )

Liked it here?
Why not try sites on the blogroll...

%d blogueiros gostam disto: