Hoje encontrei um artigo interessante: a apresentação 'Enterprise PHP development', feita por Ivo Jansch em fevereiro de 2008, na PHPLondon Conference, fala essencialmente de como desenvolver projetos sérios, de médio para grande porte, em PHP. Baixe aqui o artigo. Quem quiser ouvir a palestra, basta clicar aqui.
O autor dá uma visão geral de como profissionalizar o desenvolvimento de um projeto, usando algumas figuras de linguagem bem humoradas. Vale a pena ler.
quarta-feira, 10 de junho de 2009
segunda-feira, 6 de abril de 2009
Os 5 Ms de Ahonen
Tony Ahonen escreveu um livro entitulado "m-Profits – Making Money from 3G Services", onde discute amplamente o tema. Neste livro ele menciona os 5 Ms dos serviços 3G: "cinco elementos dos serviços 3G que agregam valor ao usuário, e lucro para a operadora".
Os 5 Ms de Ahonen
1. Movement (Movimento) - Escapando de um lugar fixo
2. Moment (Momento) - Expandindo o conceito de tempo
3. Me (Eu) - Extentendo a mim mesmo e a minha comunidade
4. Money (Dinheiro) - Gastando recursos financeiros
5. Machines (Máquinas / dispositivos) - "Turbinando" dispositivos
1. Movement.
O movimento é a habilidade do serviço a continuar operando de modo significativo enquanto que o usuário se desloca, seja por locais próximos, seja para longas distâncias.
Até aqui nenhuma novidade; o que Ahonen enfatiza como ponto-chave, é que se o serviço possuir elementos que variam de acordo com a localização do usuário, então este comportamento deve ser realizado; Ele exemplifica a previsão de tempo: se o usuário estiver transitando de uma cidade para outra, o sistema deve verificar a previsão desta nova cidade.
2. Moment
O Momento é o conceito de possibilitar a gerenciar o tempo de modo a adaptar-se a situação em que se encontra; Um bom exemplo é o serviço de mensagens publicitárias baseadas na localização do usuário: um restaurante pode ter seus anúncions distribuídos próximos do almoço, e não as 23hs da noite, para os usuários que estiverem próximos.
Outro ponto de vista do conceito de 'Moment' é a possibilidade de serem executadas várias tarefas simultaneamente: em um fluxo bem definido, tarefas relacionadas a um determinado fim podem ser distribuídas ou realizadas em paralelo, e sincronizadas pelo próprio sistema. Uma variante típica é a de iniciar uma tarefa que ficará "pendente" até o "momento certo": um exemplo é disparar a solicitação de um serviço (presencial), que será atendido daqui a 2 horas; quando chegar no local, o serviço será executado.
3. Me
"Me" é o conceito de personalização, que tem sido bem compreendido em alguns serviços Web, que adaptam-se de acordo com as configurações e perfil do usuário. Perceba que um ponto importante é o de que alguns parâmetros de configuração consistem de variáveis como o tempo (moment) e a localização (movement).
Ahonem indica que o "Me" é o atributo mais vital dos 5 apresentados: é o ingrediente crítico para um serviço móvel bem-sucedido.
Isso quer dizer que precisamos de uma plataforma flexível, o que implica em tecnologias que podem suportar um alto grau de customização, incluindo o conceito de que serviços podem algumas vezes serem construídos em tempo de execução, surgindo para atender demandas pontuais do usuário.
A criação de serviços sob demanda é um novo elemento para a provisão de serviços no contexto móvel.
4. Money
Este é simplesmente o suporte para transações financeiras, onde quer que surja a necessidade.
Evidentemente, um framework é necessário para permitir esse trabalho, dada a complexidade e a segurança envolvidas em transações de pagamentos.
5. Machines
O último 'M' é o conceito que permite que máquinas comuniquem-se através de redes WAN. Isso é algumas vezes chamado de M2M (machine to machine), e algumas vezes incrementado com a idéia de telemetria ou medições remotas sem a necessidade de pessoal de campo.
Um bom exemplo são as máquinas de venda eletrônica, como máquinas de refrigerante, que "ligam" para a central e reportam os produtos que estão acabando.
Tecendo minhas considerações
Eu creio que dos 5 Ms, os 3 primeiros são os principais, para aplicações centradas em conteúdo móvel; para tanto, o estabelecimento de uma infraestrutura lógica é fundamental, e as 3 variáveis principais são, em ordem de importância: Identificação do usuário, Localização física e Tempo.
Os 5 Ms de Ahonen
1. Movement (Movimento) - Escapando de um lugar fixo
2. Moment (Momento) - Expandindo o conceito de tempo
3. Me (Eu) - Extentendo a mim mesmo e a minha comunidade
4. Money (Dinheiro) - Gastando recursos financeiros
5. Machines (Máquinas / dispositivos) - "Turbinando" dispositivos
1. Movement.
O movimento é a habilidade do serviço a continuar operando de modo significativo enquanto que o usuário se desloca, seja por locais próximos, seja para longas distâncias.
Até aqui nenhuma novidade; o que Ahonen enfatiza como ponto-chave, é que se o serviço possuir elementos que variam de acordo com a localização do usuário, então este comportamento deve ser realizado; Ele exemplifica a previsão de tempo: se o usuário estiver transitando de uma cidade para outra, o sistema deve verificar a previsão desta nova cidade.
2. Moment
O Momento é o conceito de possibilitar a gerenciar o tempo de modo a adaptar-se a situação em que se encontra; Um bom exemplo é o serviço de mensagens publicitárias baseadas na localização do usuário: um restaurante pode ter seus anúncions distribuídos próximos do almoço, e não as 23hs da noite, para os usuários que estiverem próximos.
Outro ponto de vista do conceito de 'Moment' é a possibilidade de serem executadas várias tarefas simultaneamente: em um fluxo bem definido, tarefas relacionadas a um determinado fim podem ser distribuídas ou realizadas em paralelo, e sincronizadas pelo próprio sistema. Uma variante típica é a de iniciar uma tarefa que ficará "pendente" até o "momento certo": um exemplo é disparar a solicitação de um serviço (presencial), que será atendido daqui a 2 horas; quando chegar no local, o serviço será executado.
3. Me
"Me" é o conceito de personalização, que tem sido bem compreendido em alguns serviços Web, que adaptam-se de acordo com as configurações e perfil do usuário. Perceba que um ponto importante é o de que alguns parâmetros de configuração consistem de variáveis como o tempo (moment) e a localização (movement).
Ahonem indica que o "Me" é o atributo mais vital dos 5 apresentados: é o ingrediente crítico para um serviço móvel bem-sucedido.
Isso quer dizer que precisamos de uma plataforma flexível, o que implica em tecnologias que podem suportar um alto grau de customização, incluindo o conceito de que serviços podem algumas vezes serem construídos em tempo de execução, surgindo para atender demandas pontuais do usuário.
A criação de serviços sob demanda é um novo elemento para a provisão de serviços no contexto móvel.
4. Money
Este é simplesmente o suporte para transações financeiras, onde quer que surja a necessidade.
Evidentemente, um framework é necessário para permitir esse trabalho, dada a complexidade e a segurança envolvidas em transações de pagamentos.
5. Machines
O último 'M' é o conceito que permite que máquinas comuniquem-se através de redes WAN. Isso é algumas vezes chamado de M2M (machine to machine), e algumas vezes incrementado com a idéia de telemetria ou medições remotas sem a necessidade de pessoal de campo.
Um bom exemplo são as máquinas de venda eletrônica, como máquinas de refrigerante, que "ligam" para a central e reportam os produtos que estão acabando.
Tecendo minhas considerações
Eu creio que dos 5 Ms, os 3 primeiros são os principais, para aplicações centradas em conteúdo móvel; para tanto, o estabelecimento de uma infraestrutura lógica é fundamental, e as 3 variáveis principais são, em ordem de importância: Identificação do usuário, Localização física e Tempo.
quinta-feira, 5 de março de 2009
Filtragem de caracteres indesejáveis
Hoje o Juliano entrou em contato, pedindo uma ajuda para filtrar caracteres indesejáveis que vinham nos arquivos de dados...
Depois de muito quebrar a cabeça, conseguimos o seguinte:
1. Mudar o locale para português-Brasil
setlocale(LC_ALL,"pt_BR.ISO8859-1");
ou
setlocale(LC_ALL,"pt_BR.UTF-8");
2. Filtrar
$v = preg_replace('/[^[:blank:]|[:space:]|[:alnum:]|[:punct:]]/', ' ', $v);
Depois de muito quebrar a cabeça, conseguimos o seguinte:
1. Mudar o locale para português-Brasil
setlocale(LC_ALL,"pt_BR.ISO8859-1");
ou
setlocale(LC_ALL,"pt_BR.UTF-8");
2. Filtrar
$v = preg_replace('/[^[:blank:]|[:space:]|[:alnum:]|[:punct:]]/', ' ', $v);
segunda-feira, 2 de março de 2009
#1 - Validação de Entrada de dados (primeira parte)
Origem dos dados
Originalmente, os programadores PHP acessavam dados enviados pelos usuários através dos mecanismos de "register globals".
Usando "register globals", qualquer parâmetro passado para o script é disponibilizado como uma variável com o mesmo nome do parâmetro.
Embora o mecanismo de "register globals" seja uma abordagem para capturar parâmetros pelos scripts, é uma vulnerabilidade e possível fonte de exploração por parte de hackers.
Um dos problemas é o conflito entre os parâmetros de entrada: Dados fornecidos ao script podem vir de várias fontes, incluindo requisições GET, POST, cookies, variáveis de ambiente do servidor e variáveis de ambiente do sistema - nenhuma delas é exclusiva.
Então, se as fontes são muitas, o PHP é forçado a mesclá-las, algumas vezes substituindo o valor de uma por outra de mesmo nome. Aqui reside o perigo: se temos uma variável esperada via cookie, um atacante pode enviá-la via método GET, e o script nem perceber a diferença, se usar a variável global.
Portanto, é importante usar mecanismos que forcem a verificação da origem dos dados vindos do usuário.
No arquivo de configuração PHP.INI existem duas diretivas de controle que são usadas como parâmetros para que o interpretador faça o merge: gps_order e variables_order. Ambos parâmetros refletem a prioridade relativa das fontes de entrada de dados.
Não vamos entrar muito neste assunto, visto que já presumimos que usamos as variáveis superglobais ($_GET, $_POST, etc) para acessar tais dados. Entretanto, cabe uma orientação: mesmo usando as superglobais, existe um risco especialmente em casos em que criamos variáveis para verificar se um dado script foi carregado ou não (ou se tal arquivo pode ser incluído ou não) - nestes casos, como a variável pode estar exposta à configuração do servidor, cabe uma advertência: é melhor usar constantes (define) ao invés de usar uma variável simples. Isso porque a variável simples pode ser substituída por um parâmetro injetado por um atacante, se não estiver inicializada e dependendo da configuração do servidor.
Outra observação importante, é o uso da superglobal $_REQUEST - ela mistura as variáveis GET, POST e COOKIES em um mesmo array. É o mesmo problema da register globals, embora em menor grau. Portanto, prefira o uso de $_GET ou $_POST.
Conteúdo
É importante sempre verificar a natureza do parâmetro de entrada e validá-lo para evitar problemas depois.
Dados numéricos
Se o dado esperado é numérico, simplesmente usamos o recurso de casting para obter o valor. Veja os exemplos a seguir:
$id_produto = (int) $_GET['id_produto'];
$valor_salario = (float) $_POST['valor_salario'];
Para melhorar um pouco mais, podemos centralizar o casting onde de direito: nos getter e setters das classes:
class Funcionario {
private $valorSalario;
public function getValorSalario() {
return $this->valorSalario;
}
public setValorSalario($valor) {
$this->valorSalario = (float) $valor;
if (!$this->valorSalario) {
$e = new Exception('Valor do salario deve ser float',999);
throw $e;
}
}
}
Veja que no exemplo acima se ocorre um erro de tipo, uma excessão é imediatamente emitida e o programador já mata o problema na raiz. A abordagem acima pode ser melhorada incluindo na mensagem o valor que se está passando para o atributo em questão.
Um ponto que deve ser observado com cuidado é a precisão do tipo numérico que se espera. Por exemplo: para validar um inteiro, em sistemas de 32 bits, é 2,147,483,647. Se uma string "1000000000000000000" for convertida para integer, ela vai estourar o container e haverá perda de dados. No caso, o resultado final será truncado no máximo possível, que é 2147483647.
Então, fazendo o casting de números grandes na notação científica evitará a perda de dados:
echo (int)"100000000000000000"; // 2147483647
echo (float)"100000000000000000"; // float(1.0E+17)
Enquanto que o casting funciona bem para inteiros e números de ponto-flutuante, valores em hexadecimal, octal e descritos em notação científica não são tratados automaticamente - é necessário implementar mecanismos adicionais de validação. O mais lento mas mais eficaz é a instrução "is_numeric" - Ela suporta todos os tipos de valores numéricos, e retorna True se o valor é válido.
Problemas de internacionalização
Algumas vezes números de ponto-flutuante são representados de várias formas ao redor do mundo, mas tanto o casting quanto o "is_numeric" consideram números que não usam o "ponto" (.) como separador decimal como inválido.
O problema é que para a validação em si, não encontrei recursos nativos no PHP que consideram a entrada de dados em localizações (locales) diferentes. Os mecanismos de locales funcionam muito bem para exibir o resultado de valores no formato esperado na língua selecionada. Por isso, recomendo que se use rotinas que façam a conversão do conteúdo logo na entrada dos dados. Para o caso de dados númericos de ponto flutuante, eu uso:
$r = setlocale(LC_ALL, 'ptb');
$locale_info = localeconv();
$numero = str_replace($locale_info['thousands_sep'],"",$numero_input);
$numero = str_replace($locale_info['decimal_point'],".",$numero);
Com a lógica acima, o script "sabe" quais caracteres espera que sejam entrados pelo usuário como separador decimal e de milhar. Automaticamente o valor é convertido para o formato que o interpretador "entende", e daí para adiante o valor é processado e depois inserido/atualizado no banco de dados; Depois, a exibição do dado fica por conta do interpretador, que vai considerar o locale selecionado. No caso do exemplo acima, defini a localização como sendo Português Brasileiro.
Validação de String
A validação de string não é tão simples quanto a de um atributo numérico, uma vez que o casting não é suficiente para garantir que o valor entrado é o esperado - existem algumas variantes que precisam ser consideradas. O primeiro ponto é o formato do valor entrado, que pode ser um CPF, número de telefone, URL, CEP, etc.
Para verificar se uma string possui apenas caracteres alfabéticos, não sendo admitido qualquer número ou pontuação, pode-se usar a instrução 'ctype_alpha()'. A extensão CTYPE é habilitada por padrão no PHP. Existem outras instruções dessa extensão que podem ser úteis em questões bem particulares, mas nenhuma delas consiste regras de formação mais complexas. Veja ainda que a Ctype considera o locale ativo. Portanto, caracteres que são considerados inválidos no alfabeto inglês (como 'ç'), serão considerados válidos pela Ctype quando o locale PTB estiver setado.
Quando o ctype é inútil para resolver um determinado problema de validação, recomenda-se usar expressões regulares. Com expressões regulares é possível realizar uma série de verificações bem complexas, tanto de conteúdo quanto do posicionamento deste no corpo do texto, e também múltiplas ocorrências de padrões de conteúdo.
Para fazer tais verificações com o PHP, pode-se usar as instruções 'ereg' e seus semelhantes, bem como as instruções presentes na extensão PCRE, como a preg_match. Veja maiores detalhes do uso de cada uma destas opções no manual do PHP.
Validação de tamanho de conteúdo
Assim como dados numéricos, entradas de strings precisam atender certas especificações. As expressões regulares podem validar a sintaxe dos dados entrados, mas tabém é importante validar o tamanho da entrada.
Uma falha que pode ser explorada por um atacante, consiste na geração de um valor que excede o tamanho do campo no banco de dados, e com isso um erro de banco será emitido - se este erro não for tratado, informações valiosas para o atacante poderão ser dadas.
A solução deste problema possui duas partes: criar os formulários com mecanismos de verificação do conteúdo antes do envio dos dados ao servidor, e a verificação dos mesmos na entrada do script. Nos formulários os campos de textos podem ter tamanho máximo, com o atributo maxlength. Para campos de texto-livre (textarea) é necessário verificar o tamanho do conteúdo ao se enviar os dados, com funções javascript.
Validação de Listas de Seleção
Listas de valores onde o usuário pode selecionar um item (ou mesmo mais) é outro foco de atenção que o desenvolvedor deve ter. Veja que um atacante pode emular uma requisição injetando novos valores, que podem causar desde erros de processamento, passando por inconsistências, chegando a danificar parcialmente ou consideravelmente o sistema. Portanto, valores discretos como strings que podem ser usadas como chaves em listas de seleção, e até mesmo valores numéricos, devem ser verificados no lado do servidor antes de se prosseguir com o processamento da requisição.
Para realizar essa validação, recomenda-se o uso de uma lista de valores em um array, que será usado na verificação da consistência do valor informado.
Originalmente, os programadores PHP acessavam dados enviados pelos usuários através dos mecanismos de "register globals".
Usando "register globals", qualquer parâmetro passado para o script é disponibilizado como uma variável com o mesmo nome do parâmetro.
Embora o mecanismo de "register globals" seja uma abordagem para capturar parâmetros pelos scripts, é uma vulnerabilidade e possível fonte de exploração por parte de hackers.
Um dos problemas é o conflito entre os parâmetros de entrada: Dados fornecidos ao script podem vir de várias fontes, incluindo requisições GET, POST, cookies, variáveis de ambiente do servidor e variáveis de ambiente do sistema - nenhuma delas é exclusiva.
Então, se as fontes são muitas, o PHP é forçado a mesclá-las, algumas vezes substituindo o valor de uma por outra de mesmo nome. Aqui reside o perigo: se temos uma variável esperada via cookie, um atacante pode enviá-la via método GET, e o script nem perceber a diferença, se usar a variável global.
Portanto, é importante usar mecanismos que forcem a verificação da origem dos dados vindos do usuário.
No arquivo de configuração PHP.INI existem duas diretivas de controle que são usadas como parâmetros para que o interpretador faça o merge: gps_order e variables_order. Ambos parâmetros refletem a prioridade relativa das fontes de entrada de dados.
Não vamos entrar muito neste assunto, visto que já presumimos que usamos as variáveis superglobais ($_GET, $_POST, etc) para acessar tais dados. Entretanto, cabe uma orientação: mesmo usando as superglobais, existe um risco especialmente em casos em que criamos variáveis para verificar se um dado script foi carregado ou não (ou se tal arquivo pode ser incluído ou não) - nestes casos, como a variável pode estar exposta à configuração do servidor, cabe uma advertência: é melhor usar constantes (define) ao invés de usar uma variável simples. Isso porque a variável simples pode ser substituída por um parâmetro injetado por um atacante, se não estiver inicializada e dependendo da configuração do servidor.
Outra observação importante, é o uso da superglobal $_REQUEST - ela mistura as variáveis GET, POST e COOKIES em um mesmo array. É o mesmo problema da register globals, embora em menor grau. Portanto, prefira o uso de $_GET ou $_POST.
Conteúdo
É importante sempre verificar a natureza do parâmetro de entrada e validá-lo para evitar problemas depois.
Dados numéricos
Se o dado esperado é numérico, simplesmente usamos o recurso de casting para obter o valor. Veja os exemplos a seguir:
$id_produto = (int) $_GET['id_produto'];
$valor_salario = (float) $_POST['valor_salario'];
Para melhorar um pouco mais, podemos centralizar o casting onde de direito: nos getter e setters das classes:
class Funcionario {
private $valorSalario;
public function getValorSalario() {
return $this->valorSalario;
}
public setValorSalario($valor) {
$this->valorSalario = (float) $valor;
if (!$this->valorSalario) {
$e = new Exception('Valor do salario deve ser float',999);
throw $e;
}
}
}
Veja que no exemplo acima se ocorre um erro de tipo, uma excessão é imediatamente emitida e o programador já mata o problema na raiz. A abordagem acima pode ser melhorada incluindo na mensagem o valor que se está passando para o atributo em questão.
Um ponto que deve ser observado com cuidado é a precisão do tipo numérico que se espera. Por exemplo: para validar um inteiro, em sistemas de 32 bits, é 2,147,483,647. Se uma string "1000000000000000000" for convertida para integer, ela vai estourar o container e haverá perda de dados. No caso, o resultado final será truncado no máximo possível, que é 2147483647.
Então, fazendo o casting de números grandes na notação científica evitará a perda de dados:
echo (int)"100000000000000000"; // 2147483647
echo (float)"100000000000000000"; // float(1.0E+17)
Enquanto que o casting funciona bem para inteiros e números de ponto-flutuante, valores em hexadecimal, octal e descritos em notação científica não são tratados automaticamente - é necessário implementar mecanismos adicionais de validação. O mais lento mas mais eficaz é a instrução "is_numeric" - Ela suporta todos os tipos de valores numéricos, e retorna True se o valor é válido.
Problemas de internacionalização
Algumas vezes números de ponto-flutuante são representados de várias formas ao redor do mundo, mas tanto o casting quanto o "is_numeric" consideram números que não usam o "ponto" (.) como separador decimal como inválido.
O problema é que para a validação em si, não encontrei recursos nativos no PHP que consideram a entrada de dados em localizações (locales) diferentes. Os mecanismos de locales funcionam muito bem para exibir o resultado de valores no formato esperado na língua selecionada. Por isso, recomendo que se use rotinas que façam a conversão do conteúdo logo na entrada dos dados. Para o caso de dados númericos de ponto flutuante, eu uso:
$r = setlocale(LC_ALL, 'ptb');
$locale_info = localeconv();
$numero = str_replace($locale_info['thousands_sep'],"",$numero_input);
$numero = str_replace($locale_info['decimal_point'],".",$numero);
Com a lógica acima, o script "sabe" quais caracteres espera que sejam entrados pelo usuário como separador decimal e de milhar. Automaticamente o valor é convertido para o formato que o interpretador "entende", e daí para adiante o valor é processado e depois inserido/atualizado no banco de dados; Depois, a exibição do dado fica por conta do interpretador, que vai considerar o locale selecionado. No caso do exemplo acima, defini a localização como sendo Português Brasileiro.
Validação de String
A validação de string não é tão simples quanto a de um atributo numérico, uma vez que o casting não é suficiente para garantir que o valor entrado é o esperado - existem algumas variantes que precisam ser consideradas. O primeiro ponto é o formato do valor entrado, que pode ser um CPF, número de telefone, URL, CEP, etc.
Para verificar se uma string possui apenas caracteres alfabéticos, não sendo admitido qualquer número ou pontuação, pode-se usar a instrução 'ctype_alpha()'. A extensão CTYPE é habilitada por padrão no PHP. Existem outras instruções dessa extensão que podem ser úteis em questões bem particulares, mas nenhuma delas consiste regras de formação mais complexas. Veja ainda que a Ctype considera o locale ativo. Portanto, caracteres que são considerados inválidos no alfabeto inglês (como 'ç'), serão considerados válidos pela Ctype quando o locale PTB estiver setado.
Quando o ctype é inútil para resolver um determinado problema de validação, recomenda-se usar expressões regulares. Com expressões regulares é possível realizar uma série de verificações bem complexas, tanto de conteúdo quanto do posicionamento deste no corpo do texto, e também múltiplas ocorrências de padrões de conteúdo.
Para fazer tais verificações com o PHP, pode-se usar as instruções 'ereg' e seus semelhantes, bem como as instruções presentes na extensão PCRE, como a preg_match. Veja maiores detalhes do uso de cada uma destas opções no manual do PHP.
Validação de tamanho de conteúdo
Assim como dados numéricos, entradas de strings precisam atender certas especificações. As expressões regulares podem validar a sintaxe dos dados entrados, mas tabém é importante validar o tamanho da entrada.
Uma falha que pode ser explorada por um atacante, consiste na geração de um valor que excede o tamanho do campo no banco de dados, e com isso um erro de banco será emitido - se este erro não for tratado, informações valiosas para o atacante poderão ser dadas.
A solução deste problema possui duas partes: criar os formulários com mecanismos de verificação do conteúdo antes do envio dos dados ao servidor, e a verificação dos mesmos na entrada do script. Nos formulários os campos de textos podem ter tamanho máximo, com o atributo maxlength. Para campos de texto-livre (textarea) é necessário verificar o tamanho do conteúdo ao se enviar os dados, com funções javascript.
Validação de Listas de Seleção
Listas de valores onde o usuário pode selecionar um item (ou mesmo mais) é outro foco de atenção que o desenvolvedor deve ter. Veja que um atacante pode emular uma requisição injetando novos valores, que podem causar desde erros de processamento, passando por inconsistências, chegando a danificar parcialmente ou consideravelmente o sistema. Portanto, valores discretos como strings que podem ser usadas como chaves em listas de seleção, e até mesmo valores numéricos, devem ser verificados no lado do servidor antes de se prosseguir com o processamento da requisição.
Para realizar essa validação, recomenda-se o uso de uma lista de valores em um array, que será usado na verificação da consistência do valor informado.
sexta-feira, 27 de fevereiro de 2009
Um pouco mais sobre segurança de arquiteturas web
Autenticação
Dicas importantes:
Autenticação de Realm
Realm significa 'domínio' ou 'reino'. Tratando-se de ambiente de aplicações web, 'realm' significa uma área protegida.
Autenticação de Realm é usada para proteger recursos dentro de um domínio que está disponível apenas para usuários autorizados.
O método de autenticação para um 'realm' consiste em registrar um módulo de autenticação para o domínio e definir os atributos de configuração. Isso é feito a nível de servidor web.
Passo-a-passo
Quando um recurso em particular dentro do domínio é protegido usando a autenticação básica, e quando um usuário tenta acessá-lo, o servidor web envia um cabeçalho de requisição de autenticação (código 401) para o requisitante. Isso notifica o navegador que o recurso não pode ser acessado sem autenticação; em resposta, as credenciais do usuário devem ser supridas para que o recurso requisitado possa ser recuperado. Um formulário de login e senha é aberto pelo browser solicitando ao usuário que entre com seu username e senha. Você pode definir o método de autenticação como Basic ou Digest.
Nunca use o método básico, porque nesta forma o usuário e a senha são enviados com cleartext, enquanto que no modo Digest a senha é codificada pelo browser usando o algoritmo MD5. Assim, se algum sniffer capturar os dados trocados entre o cliente e o servidor, só terá o hash, e não a senha.
A autenticação baseada em Realm é diferente da autenticação de 'Realm'; Na autenticação baseada em Realm, o usuário pode se autenticar para um domínio ou subdomínio (subrealm). Você define diferentes domínios para recursos diferentes, e a autenticação do realm pode ser especificada em uma interface de login como parte da URL pela definição do parâmetro do realm ou parâmetro do domínio.
Gerenciamento de Arquivos de Configuração
Um sistema é a coleção de muitas partes. Estas partes geralmente incluem programas executáveis, arquivos de parâmetros para customizar o software para um determinado ambiente, e dados.
Se um adversário obtém o arquivo de configuração, todo o sistema pode vir a estar vulnerável.
Por isso é especialmente crítico que estes arquivos de parâmetros e de configuração sejam mantidos em segurança. Além disso, todos os aplicativos que acessem tais arquivos devem ter os privilégios adequados. Para maior proteção da segurança, as seguintes medidas precisam ser tomadas:
Gerenciamento de Sessões
Partindo do princípio de que o protocolo HTTP é stateless, é necessário que se mantenha o estado das aplicações através de sessões. As informações de estado da sessão é transferida do browser em algum formato que sempre é devolvido para o servidor como o contexto do cliente. Esta informação do contexto é crítica para o gerenciamento da sessão e o estado do contexto da mesma. Se um adversário rouba o contexto e o usa em outro terminal dentro do período válido, é possível que ele possa roubar a sessão e assumir a identidade do usuário real.
Estas medidas vão ajudar a evitar ataques como 'session hijacking', 'session replay', e 'man-in-the middle'.
Code Injection
No ambiente web, a maioria dos relatos de code injection são de códigos SQL aplicados com o intuito de obter acesso às bases de dados.
A raiz de todos os problemas de code injection é que os desenvolvedores colocam muita confiança nos usuários das aplicações. Entretanto, nem todos os usuários na web farão o que o desenvolvedor da aplicação espera.
Como exemplo, uma pessoa não precisa necessariamente de um browser para acessar a aplicação. De fato, um atacante experiente não usará um browser como o Internet Explorer ou Firefox: o atacante usará um navegador feito especificamente para toda a sorte de coisas ilícitas.
Como arquiteto de segurança, você não deve nunca confiar no usuário, ou acreditar que ele está operando a aplicação de modo seguro e esperar que ele aja da forma como você deseja. Esta é uma vulnerabilidade relacionada com a programação da aplicação.
Ataque Denial-of-Service (DoS)
Em um ataque DoS, o atacante dispara diferentes ataques de segurança para encontrar uma aplicação ou serviço que não possa ser usado por usuários legitimados. Então, forçando o serviço a estar indisponível é considerado um ataque DoS. Isto pode ocorrer nas seguintes áreas:
Tratamento de erros
Para tornar o software mais amigável, nós geramos mensagens de erros mais acessíveis. De acordo com a prática de engenharia de software, é recomendado que as mensagens de erro sejam incluídas como parte do projeto. Além disso, tais mensagens devem ter significado claro e devem ser detalhadas. A filosofia por trás da mensagem de erro é que o usuário deve obter informações o suficiente para corrigir o erro e executar os próximos passos corretamente. As mensagens de erro possuem informações de alto-nível sobre o sistema, e isso é um risco em aplicações web;
Geralmente atacantes deliberadamente entram com entradas incorretas para verificar o comportamento do sistema. Alguns campos são esperados que sejam preenchidos na interface do usuário; mensagens de erro detalhadas podem ajudar o atacante a conhecer o comportamento do programa. Portanto, enquanto você está projetando o sistema, você deve manter uma coisa em mente: você deve dar o mínimo possível, mas necessárias, informações nas mensagens de erro.
Fonte: Architecting Secure Software Systems,
Dicas importantes:
- Use senhas fortes
- Não armazene credenciais sem estarem codificadas em arquivos de codificação
- Não transmita arquivos sem estarem criptografados pela rede
- Não permita contas super-privilegiadas
- Não permita sessões com tempo de vida prolongado
- Permita a personalização e o armazenamento de informações de autenticação
Autenticação de Realm
Realm significa 'domínio' ou 'reino'. Tratando-se de ambiente de aplicações web, 'realm' significa uma área protegida.
Autenticação de Realm é usada para proteger recursos dentro de um domínio que está disponível apenas para usuários autorizados.
O método de autenticação para um 'realm' consiste em registrar um módulo de autenticação para o domínio e definir os atributos de configuração. Isso é feito a nível de servidor web.
Passo-a-passo
Quando um recurso em particular dentro do domínio é protegido usando a autenticação básica, e quando um usuário tenta acessá-lo, o servidor web envia um cabeçalho de requisição de autenticação (código 401) para o requisitante. Isso notifica o navegador que o recurso não pode ser acessado sem autenticação; em resposta, as credenciais do usuário devem ser supridas para que o recurso requisitado possa ser recuperado. Um formulário de login e senha é aberto pelo browser solicitando ao usuário que entre com seu username e senha. Você pode definir o método de autenticação como Basic ou Digest.
Nunca use o método básico, porque nesta forma o usuário e a senha são enviados com cleartext, enquanto que no modo Digest a senha é codificada pelo browser usando o algoritmo MD5. Assim, se algum sniffer capturar os dados trocados entre o cliente e o servidor, só terá o hash, e não a senha.
A autenticação baseada em Realm é diferente da autenticação de 'Realm'; Na autenticação baseada em Realm, o usuário pode se autenticar para um domínio ou subdomínio (subrealm). Você define diferentes domínios para recursos diferentes, e a autenticação do realm pode ser especificada em uma interface de login como parte da URL pela definição do parâmetro do realm ou parâmetro do domínio.
Gerenciamento de Arquivos de Configuração
Um sistema é a coleção de muitas partes. Estas partes geralmente incluem programas executáveis, arquivos de parâmetros para customizar o software para um determinado ambiente, e dados.
Se um adversário obtém o arquivo de configuração, todo o sistema pode vir a estar vulnerável.
Por isso é especialmente crítico que estes arquivos de parâmetros e de configuração sejam mantidos em segurança. Além disso, todos os aplicativos que acessem tais arquivos devem ter os privilégios adequados. Para maior proteção da segurança, as seguintes medidas precisam ser tomadas:
- Use interfaces de administração seguras;
- Armazene as informações de configuração em áreas de armazenamento seguras;
- Qualquer dado sensível que está sendo armazenado em bases persistentes como seus resultados parciais devem ser atômicos - sempre delete se a transação for tanto bem-sucedida quanto quando falhar - Isso é especialmente útil para evitar que um atacante venha a tentar "quebrar" a aplicação para deixar o arquivo intermediário disponível para leitura.
- Evita armazenar dados de configuração em cleartext.
- Evite muitos administradores e múltiplas interfaces de administração.
Gerenciamento de Sessões
Partindo do princípio de que o protocolo HTTP é stateless, é necessário que se mantenha o estado das aplicações através de sessões. As informações de estado da sessão é transferida do browser em algum formato que sempre é devolvido para o servidor como o contexto do cliente. Esta informação do contexto é crítica para o gerenciamento da sessão e o estado do contexto da mesma. Se um adversário rouba o contexto e o usa em outro terminal dentro do período válido, é possível que ele possa roubar a sessão e assumir a identidade do usuário real.
- Passe os identificadores da sessão apenas por canais criptografados;
- Não permita sessões com tempo de vida muito prolongados
- Não armazene o estado da sessão em um repositório inseguro - cuidado especial com a localização do arquivo ou tabela onde são armazenados os dados da sessão, pois se um atacante obtém acesso a eles, pode obter informações valiosas além do identificador da sessão em si.
- Evite colocar o identificador de sessão em URLs.
Estas medidas vão ajudar a evitar ataques como 'session hijacking', 'session replay', e 'man-in-the middle'.
Code Injection
No ambiente web, a maioria dos relatos de code injection são de códigos SQL aplicados com o intuito de obter acesso às bases de dados.
- Aqui o atacante pode querer acesso a áreas que normalmente estão disponíveis apenas para usuários com outros níveis de acesso.
- Podem querer também roubar informações importantes, como dados pessoais, dados bancários, de cartões de crédito e identificações de outros sistemas.
- Em casos de espionagem industrial, o atacante pode querer adulterar a base de dados.
- Por fim, um atacante pode tentar excluir completamente uma base de dados, causando DoS (Denial of Service - Negação de Serviço)
A raiz de todos os problemas de code injection é que os desenvolvedores colocam muita confiança nos usuários das aplicações. Entretanto, nem todos os usuários na web farão o que o desenvolvedor da aplicação espera.
Como exemplo, uma pessoa não precisa necessariamente de um browser para acessar a aplicação. De fato, um atacante experiente não usará um browser como o Internet Explorer ou Firefox: o atacante usará um navegador feito especificamente para toda a sorte de coisas ilícitas.
Como arquiteto de segurança, você não deve nunca confiar no usuário, ou acreditar que ele está operando a aplicação de modo seguro e esperar que ele aja da forma como você deseja. Esta é uma vulnerabilidade relacionada com a programação da aplicação.
Ataque Denial-of-Service (DoS)
Em um ataque DoS, o atacante dispara diferentes ataques de segurança para encontrar uma aplicação ou serviço que não possa ser usado por usuários legitimados. Então, forçando o serviço a estar indisponível é considerado um ataque DoS. Isto pode ocorrer nas seguintes áreas:
- SO: Ele pode ser a nível de servidor, que está hospedando uma aplicação ou servidor web - o ataque pode ser centrado em alguma vulnerabilidade do sistema operacional, com o intuito de quebrá-lo.
- Protocolo: O ataque também pode ser focado no protocolo TCP/IP. Um ataque comum é o 'half open TCP', onde o buffer TCP é exaurido para disparar o ataque.
- Servidor Web: Pode ser em uma vulnerabilidade do servidor Web. Neste tipo de ataque, o atacante explora uma vulnerabilidade do servidor Web, como um IIS ou Apache.
- Aplicação: Pode ser uma vulnerabilidade da aplicação. Isso pode ser feito forçando a aplicação a entrar em looping, quebrar ou mesmo entrar em deadlock.
Tratamento de erros
Para tornar o software mais amigável, nós geramos mensagens de erros mais acessíveis. De acordo com a prática de engenharia de software, é recomendado que as mensagens de erro sejam incluídas como parte do projeto. Além disso, tais mensagens devem ter significado claro e devem ser detalhadas. A filosofia por trás da mensagem de erro é que o usuário deve obter informações o suficiente para corrigir o erro e executar os próximos passos corretamente. As mensagens de erro possuem informações de alto-nível sobre o sistema, e isso é um risco em aplicações web;
Geralmente atacantes deliberadamente entram com entradas incorretas para verificar o comportamento do sistema. Alguns campos são esperados que sejam preenchidos na interface do usuário; mensagens de erro detalhadas podem ajudar o atacante a conhecer o comportamento do programa. Portanto, enquanto você está projetando o sistema, você deve manter uma coisa em mente: você deve dar o mínimo possível, mas necessárias, informações nas mensagens de erro.
Fonte: Architecting Secure Software Systems,
quinta-feira, 26 de fevereiro de 2009
1. Validação de Entrada de dados
Um dos princípios que devem ser sempre observados em sistemas web, é o de que as entradas de dados são essencialmente inseguras - isso quer dizer que os dados são geralmente não confiáveis.
Até o momento em que os dados chegam ao script PHP, estes saíram do browser do cliente, passaram por um conjunto de nós de rede que incluem proxys, firewals, ferramentas de filtragem, etc. Qualquer um destes passos possui atrelada uma oportunidade - seja intencional ou acidental, de corromper ou alterar os dados de modo inesperado.
Considerando ainda que os dados podem ser adulterados neste longo caminho, ou mesmo forjados por atacantes que obtiveram informações privilegiadas a partir deste ou de outros sistemas, é absolutamente imperativo que todos os dados de entrada no sistema sejam validados para garantir que eles batam com os formatos e conteúdos esperados.
Embora a validação dos dados não seja a solução universal para todos os problemas de segurança que possam haver em um sistema, boa parte das falhas podem ser corrigidas assumindo a postura de validação total.
Isso inclui:
Até o momento em que os dados chegam ao script PHP, estes saíram do browser do cliente, passaram por um conjunto de nós de rede que incluem proxys, firewals, ferramentas de filtragem, etc. Qualquer um destes passos possui atrelada uma oportunidade - seja intencional ou acidental, de corromper ou alterar os dados de modo inesperado.
Considerando ainda que os dados podem ser adulterados neste longo caminho, ou mesmo forjados por atacantes que obtiveram informações privilegiadas a partir deste ou de outros sistemas, é absolutamente imperativo que todos os dados de entrada no sistema sejam validados para garantir que eles batam com os formatos e conteúdos esperados.
Embora a validação dos dados não seja a solução universal para todos os problemas de segurança que possam haver em um sistema, boa parte das falhas podem ser corrigidas assumindo a postura de validação total.
Isso inclui:
- a verificação dos tipos de dados - como datas, numéricos, alfanuméricos, etc.
- a checagem do tamanho máximo permitido - um campo deve ter especificado o número mínimo e máximo de caracteres que deve ser informado; evidentemente que campos não obrigatórios possuem o tamanho mínimo igual a zero.
- a verificação da consistência do conteúdo tem como objetivo analisar se o padrão do conteúdo está dentro do esperado - campos com máscara ou formato tais como CEP, CPF, CNPJ, são bons exemplos disso.
- o teste de consistência lógica - códigos informados podem ser verificados antes de proceder com as demais atividades; isso quer dizer, que em alguns casos, podemos verificar se determinado registro existe na base de dados.
- o teste de código injetado - verificar se o campo possui código suspeito, como instruções SQL, HTML ou javascript.
Guide to PHP Security #1
Este é o início de uma série que pretendo postar, onde vou traduzir e comentar trechos do Guia para Segurança em PHP (Guide to PHP Security).
Abaixo seguem os capítulos do livro:
1. Validação de Entrada de dados
2. Prevenção de Cross-Site Scripting (CSS)
3. SQL Injection
4. Preveningo Code Injection
5. Command Injection
6. Segurança de Sessão
7. Segurança de acesso a arquivos
8. Segurança através da obscuridade
9. Sandboxes e Tar Pits
10. Fazendo com que sua aplicação seja segura
Abaixo seguem os capítulos do livro:
1. Validação de Entrada de dados
2. Prevenção de Cross-Site Scripting (CSS)
3. SQL Injection
4. Preveningo Code Injection
5. Command Injection
6. Segurança de Sessão
7. Segurança de acesso a arquivos
8. Segurança através da obscuridade
9. Sandboxes e Tar Pits
10. Fazendo com que sua aplicação seja segura
quarta-feira, 25 de fevereiro de 2009
Vulnerabilidades de uma aplicacao Web
Podemos notar alguns pontos de vulnerabilidades em sistemas web, tais como:
Web-client - browser e outros aplicativos que se comunicam com o sistema; pode sofrer ataques de engenharia reversa, onde falhas de seguranca sao procuradas e exploradas pelo atacante.
Comunicacao entre o web-client e o web-server - o canal de comunicacao entre os dois componentes, pode ser investigado atraves de sniffers e outras ferramentas. Os ataques podem ser adulteracao de conteudo (Parameter tampering) e negacao de servicos (Denial of service).
Web-client - browser e outros aplicativos que se comunicam com o sistema; pode sofrer ataques de engenharia reversa, onde falhas de seguranca sao procuradas e exploradas pelo atacante.
Comunicacao entre o web-client e o web-server - o canal de comunicacao entre os dois componentes, pode ser investigado atraves de sniffers e outras ferramentas. Os ataques podem ser adulteracao de conteudo (Parameter tampering) e negacao de servicos (Denial of service).
Principios de seguranca de sistemas Web
Principio #1 - O defensor deve defender todos os pontos; o atacante pode escolher o ponto mais fraco.
Principio #2 - O defensor pode defender somente contra ataques conhecidos; o ataque pode testar por vulnerabilidades desconhecidas.
Principio #3 - O defensor deve estar constantemente vigilante; o atacante podera atacar quando ele puder.
Principio #4 - O defensor deve jogar pelas regras; o atacante pode jogar sujo.
Principio #5 - O defensor deve ser bem-sucedido em todo o tempo, defendendo seu sistema; o atacante precisa ser bem-sucedido apenas uma vez.
Principio #6 - O protetor precisa conhecer o sistema a ser protegido e como protege-lo de ataques; o atacante usa aplicativos-robos para gerar combinacoes e padroes de ataque que sao lancados arbitrariamente sem se preocupar com os recursos - para o atacante, a unica restricao e o tempo.
Principio #2 - O defensor pode defender somente contra ataques conhecidos; o ataque pode testar por vulnerabilidades desconhecidas.
Principio #3 - O defensor deve estar constantemente vigilante; o atacante podera atacar quando ele puder.
Principio #4 - O defensor deve jogar pelas regras; o atacante pode jogar sujo.
Principio #5 - O defensor deve ser bem-sucedido em todo o tempo, defendendo seu sistema; o atacante precisa ser bem-sucedido apenas uma vez.
Principio #6 - O protetor precisa conhecer o sistema a ser protegido e como protege-lo de ataques; o atacante usa aplicativos-robos para gerar combinacoes e padroes de ataque que sao lancados arbitrariamente sem se preocupar com os recursos - para o atacante, a unica restricao e o tempo.
quarta-feira, 7 de janeiro de 2009
Prototipando interface de usuario
Pensando muito no processo de desenvolvimento, entendi que é muito importante que seja feita a prototipação da interface com o usuário. Mas existem questões como:
Em primeiro lugar, temos que definir a necessidade do protótipo visual, e seu papel no processo de desenvolvimento. Na minha opinião, o protótipo visual servirá para obter a aprovação junto ao usuário, do que é esperado como interface com o sistema. Então uma premissa que deve ser estabelecida é: a criação do protótipo deve ser feita na frente do usuário. Isso porque se formos fazer anotações e depois montar o protótipo, apresentando-o em outro momento, podemos perder detalhes do que foi conversado, e o usuario poderá esquecer de itens que foram tratados ou até mesmo já ter criado novas espectativas. Isso nos leva a outro ponto muito importante: Para que o protótipo seja feito na frente do usuário, a ferramenta de desenho deve ser ágil e produtiva: se a sessão de prototipação demorar demais, podemos perder a atenção do usuário, e assim tornar a reunião cansativa demais. Assim, ou adotamos uma ferramenta digital, como a Balsamiq Mockups, ou desenhamos em folhas de papel, que depois podem ser digitalizadas. A vantagem da folha de papel é a liberdade em desenhar componentes e fazer anotações. Seus problemas são a leitura de letras de difícil compreensão e a dificuldade de rearranjar facilmente os componentes. A vantagem de uma ferramenta como a Balsamiq é que o desenho, embora não funcional, já fica armazenado e permite mudanças rápidas. É bem amigável e funciona bem para interfaces relativamente complexas. Podemos até arriscar a deixar um cliente mais experiente no uso do computador desenhando as telas desejadas. O problema é quando se deseja usar componentes que não existem - neste caso recomendo usar anotações mesmo.
Bom, já comecamos definindo implicitamente que o protótipo não sera funcional, ou seja, será apenas um anexo na documentação de análise. Entretanto, a menos que use uma ferramenta como o Adobe Flex Builder, ou interface de linguagem de 4a geração, podemos perder mais tempo desenhando uma interface bem elaborada, quando poderíamos deixar os detalhes para depois. Então, a menos que se tenha um ferramental ágil para desenvolver o protótipo funcional inicial, vamos optar pelo estático mesmo.
Uma vez que o protótipo tenha sido desenhado e pré-aprovado pelo cliente, então podemos partir para desenvolver a interface do usuário, mandando as imagens do rascunho inicial para que o designer possa desenvolver os componentes. Recomendo que nesta fase, que pode ser realizada enquanto se faz o projeto físico, faça-se apenas os formulários, sem atuação de um componente Action (ainda). A idéia é que no final da etapa de projeto lógico e físico, seja apresentada a interface para o usuário - dependendo do grau de experiência do cliente, do tempo disponível e da dimensão do sistema, podemos apresentar o protótipo inicial, as telas como vão ficar, os casos de uso, a lista de requisitos e o modelo de domínio simplificado.
Uma vez aprovado, podemos partir para o desenvolvimento dos actions com as respostas e apresentar logo em seguida - isso dará um senso de organização e de que o trabalho esta fluindo bem.
Já que firmamos a linha-mestra e alguns princípios, vamos discutir um pouco mais sobre como funcionarão as coisas em um caso tipico.
Considerando um sistema simples, com a maioria dos formulários sendo apenas CRUD, podemos focar apenas em um ou dois para obter o sentimento do usuário, e depois dar maior importância para os formulários mais complexos. A desenhos do protótipo inicial deverão ser arquivados junto com o modelo do sistema, ficando disponíveis para todos envolvidos no projeto. Para isso, cria-se um objeto "artifact" no modelo do EA, associando-o com arquivo do protótipo. Após sua aprovação formal pelo usuário (que preferencialmente deve ocorrer no momento da entrevista), o designer entra em ação, criando a interface em HTML e javascript propriamente dita. As alterações que forem sendo feitas não precisam necessariamente ser replicadas no desenho feito, mas recomenda-se pelo menos documentar as mudancas feitas, justificando o porque de não fazer, fazer diferente ou incluir determinado componente. Este tipo de registro deve ser feito no EA, como uma lista de questões ligadas a este artefato. Estas questões deverão ser recuperadas pelo sistema gestão de desenvolvimento e manutenção (atrelado ao Dotproject), e serão usados no relatório do projeto.
O resultado final poderá também gerar um screenshot que será anexado ao mesmo artifact (com o label de "feito").
- criar protótipo dinâmico ou estático?
- criar um protótipo reutilizável?
- o que fazer com o protótipo na fase de construção?
Em primeiro lugar, temos que definir a necessidade do protótipo visual, e seu papel no processo de desenvolvimento. Na minha opinião, o protótipo visual servirá para obter a aprovação junto ao usuário, do que é esperado como interface com o sistema. Então uma premissa que deve ser estabelecida é: a criação do protótipo deve ser feita na frente do usuário. Isso porque se formos fazer anotações e depois montar o protótipo, apresentando-o em outro momento, podemos perder detalhes do que foi conversado, e o usuario poderá esquecer de itens que foram tratados ou até mesmo já ter criado novas espectativas. Isso nos leva a outro ponto muito importante: Para que o protótipo seja feito na frente do usuário, a ferramenta de desenho deve ser ágil e produtiva: se a sessão de prototipação demorar demais, podemos perder a atenção do usuário, e assim tornar a reunião cansativa demais. Assim, ou adotamos uma ferramenta digital, como a Balsamiq Mockups, ou desenhamos em folhas de papel, que depois podem ser digitalizadas. A vantagem da folha de papel é a liberdade em desenhar componentes e fazer anotações. Seus problemas são a leitura de letras de difícil compreensão e a dificuldade de rearranjar facilmente os componentes. A vantagem de uma ferramenta como a Balsamiq é que o desenho, embora não funcional, já fica armazenado e permite mudanças rápidas. É bem amigável e funciona bem para interfaces relativamente complexas. Podemos até arriscar a deixar um cliente mais experiente no uso do computador desenhando as telas desejadas. O problema é quando se deseja usar componentes que não existem - neste caso recomendo usar anotações mesmo.
Bom, já comecamos definindo implicitamente que o protótipo não sera funcional, ou seja, será apenas um anexo na documentação de análise. Entretanto, a menos que use uma ferramenta como o Adobe Flex Builder, ou interface de linguagem de 4a geração, podemos perder mais tempo desenhando uma interface bem elaborada, quando poderíamos deixar os detalhes para depois. Então, a menos que se tenha um ferramental ágil para desenvolver o protótipo funcional inicial, vamos optar pelo estático mesmo.
Uma vez que o protótipo tenha sido desenhado e pré-aprovado pelo cliente, então podemos partir para desenvolver a interface do usuário, mandando as imagens do rascunho inicial para que o designer possa desenvolver os componentes. Recomendo que nesta fase, que pode ser realizada enquanto se faz o projeto físico, faça-se apenas os formulários, sem atuação de um componente Action (ainda). A idéia é que no final da etapa de projeto lógico e físico, seja apresentada a interface para o usuário - dependendo do grau de experiência do cliente, do tempo disponível e da dimensão do sistema, podemos apresentar o protótipo inicial, as telas como vão ficar, os casos de uso, a lista de requisitos e o modelo de domínio simplificado.
Uma vez aprovado, podemos partir para o desenvolvimento dos actions com as respostas e apresentar logo em seguida - isso dará um senso de organização e de que o trabalho esta fluindo bem.
Já que firmamos a linha-mestra e alguns princípios, vamos discutir um pouco mais sobre como funcionarão as coisas em um caso tipico.
Considerando um sistema simples, com a maioria dos formulários sendo apenas CRUD, podemos focar apenas em um ou dois para obter o sentimento do usuário, e depois dar maior importância para os formulários mais complexos. A desenhos do protótipo inicial deverão ser arquivados junto com o modelo do sistema, ficando disponíveis para todos envolvidos no projeto. Para isso, cria-se um objeto "artifact" no modelo do EA, associando-o com arquivo do protótipo. Após sua aprovação formal pelo usuário (que preferencialmente deve ocorrer no momento da entrevista), o designer entra em ação, criando a interface em HTML e javascript propriamente dita. As alterações que forem sendo feitas não precisam necessariamente ser replicadas no desenho feito, mas recomenda-se pelo menos documentar as mudancas feitas, justificando o porque de não fazer, fazer diferente ou incluir determinado componente. Este tipo de registro deve ser feito no EA, como uma lista de questões ligadas a este artefato. Estas questões deverão ser recuperadas pelo sistema gestão de desenvolvimento e manutenção (atrelado ao Dotproject), e serão usados no relatório do projeto.
O resultado final poderá também gerar um screenshot que será anexado ao mesmo artifact (com o label de "feito").
terça-feira, 6 de janeiro de 2009
Engenharia de Negocios para o Desenvolvimento Agil
A partir desta introducao de arquitetura de negocios, vamos...
A abordagem tipica que e' usada para projetar e construir sistemas empresariais com metodos de desenvolvimento de sistemas tradicionais, pode ser resumida como:
1) Os requisitos de sistemas sao tipicamente definidos pela equipe de TI, atraves de entrevistas com usuarios, para determinar suas necessidades operacionais e de negocio;
2) O projeto que e' definido e' tanto baseado na tecnologia, com projeto da aplicacao, de banco de dados e objetos, refletindo esta tecnologia;
3) Este projeto e' implementado para atender os requisitos desejados para o negocio.
Esta abordagem tradicional para desenvolvimento de sistemas tem sido dependente da tecnologia, e sua adocao resulta nos seguintes problemas:
1) As necessidades de negocio sao dificeis de se determinar - se uma necessidade nao for compreendida ou expressa claramente, o projetista de sistemas nao a enderecara as reais necessidades dos usuarios e dos gerentes;
2) Os sistemas que sao desenvolvidos nao sao alinhados com os objetivos corporativos que definem as direcoes para o futuro. Este e' um dos maiores problemas com o desenvolvimento de sistemas atualmente.
3) As direcoes estrategicas nao sao claras - ainda assim elas devem ser compreendidas pela area de TI, para projetar sistemas flexiveis que suportem mudancas estrategicas de direcao.
Na realidade, os problemas com os metodos tradicionais de desenvolvimento sao muito maiores que o sugerido na lista acima. As necessidades do negocio tem sido tradicionalmente sido decididas pela revisao dos processos operacionais do negocio. Estes processos foram determinados baseando-se nos planos estrategicos tipicamente definidos muitos anos atras, algumas vezes, mais de uma decada atras.
Ainda na decada de 90, nao temos ideia de que seria possivel fazer as coisas que fazemos, ou o que podemos fazer atraves da comunicacao instantanea com os clientes, fornecedores e parceiros de negocios em qualquer lugar do mundo, atraves da Internet. O ambiente que aceitamos hoje como normal estava alem da imaginacao da maioria.
Os planos estrategicos definidos na decada de 90 nao anteciparam o que estas organizacoes poderiam fazer hoje, comunicando-se com cada um em poucos segundos. Eles assumiram que as comunicacoes seriam sempre feitas via cartas, ou talvez por fax, com respostas recebidas dias ou semanas depois. Assumia-se que as respostas mais rapida destes processos de negocio seriam feitas em horas. Os processos de negocio nao foram projetados para serem respondidos em segundos.
Este ponto e' de importancia vital e deve ser enfatizado:
*As abordagens tradicionais de desenvolvimento de sistemas - baseadas em entrevistas com usuarios em processos de negocio e identificando suas necessidades futuras - nao trabalha bem com periodos em que as mudancas ocorrem muito rapidamente, como atualmente.*
pg 49
A abordagem tipica que e' usada para projetar e construir sistemas empresariais com metodos de desenvolvimento de sistemas tradicionais, pode ser resumida como:
1) Os requisitos de sistemas sao tipicamente definidos pela equipe de TI, atraves de entrevistas com usuarios, para determinar suas necessidades operacionais e de negocio;
2) O projeto que e' definido e' tanto baseado na tecnologia, com projeto da aplicacao, de banco de dados e objetos, refletindo esta tecnologia;
3) Este projeto e' implementado para atender os requisitos desejados para o negocio.
Esta abordagem tradicional para desenvolvimento de sistemas tem sido dependente da tecnologia, e sua adocao resulta nos seguintes problemas:
1) As necessidades de negocio sao dificeis de se determinar - se uma necessidade nao for compreendida ou expressa claramente, o projetista de sistemas nao a enderecara as reais necessidades dos usuarios e dos gerentes;
2) Os sistemas que sao desenvolvidos nao sao alinhados com os objetivos corporativos que definem as direcoes para o futuro. Este e' um dos maiores problemas com o desenvolvimento de sistemas atualmente.
3) As direcoes estrategicas nao sao claras - ainda assim elas devem ser compreendidas pela area de TI, para projetar sistemas flexiveis que suportem mudancas estrategicas de direcao.
Na realidade, os problemas com os metodos tradicionais de desenvolvimento sao muito maiores que o sugerido na lista acima. As necessidades do negocio tem sido tradicionalmente sido decididas pela revisao dos processos operacionais do negocio. Estes processos foram determinados baseando-se nos planos estrategicos tipicamente definidos muitos anos atras, algumas vezes, mais de uma decada atras.
Ainda na decada de 90, nao temos ideia de que seria possivel fazer as coisas que fazemos, ou o que podemos fazer atraves da comunicacao instantanea com os clientes, fornecedores e parceiros de negocios em qualquer lugar do mundo, atraves da Internet. O ambiente que aceitamos hoje como normal estava alem da imaginacao da maioria.
Os planos estrategicos definidos na decada de 90 nao anteciparam o que estas organizacoes poderiam fazer hoje, comunicando-se com cada um em poucos segundos. Eles assumiram que as comunicacoes seriam sempre feitas via cartas, ou talvez por fax, com respostas recebidas dias ou semanas depois. Assumia-se que as respostas mais rapida destes processos de negocio seriam feitas em horas. Os processos de negocio nao foram projetados para serem respondidos em segundos.
Este ponto e' de importancia vital e deve ser enfatizado:
*As abordagens tradicionais de desenvolvimento de sistemas - baseadas em entrevistas com usuarios em processos de negocio e identificando suas necessidades futuras - nao trabalha bem com periodos em que as mudancas ocorrem muito rapidamente, como atualmente.*
pg 49
Assinar:
Postagens (Atom)