No início do guia, dissemos que a filtragem de dados é a base da segurança de aplicações WEB em qualquer idioma e em qualquer plataforma. Isso inclui verificar a entrada de dados de e para o aplicativo, e um bom design de software pode ajudar os desenvolvedores
a garantir que a filtragem de dados não possa ser ignorada,
garantir que as informações ilegais não afetem as informações legais e
identificar a fonte dos dados.
Existem vários pontos de vista sobre como garantir que a filtragem de dados não pode ser contornada, e dois deles são mais gerais do que outros e fornecem um nível mais elevado de garantia.
Método de agendamento Este método é agendado com um único script PHP (via URL). Quaisquer outras operações são incluídas usando include ou require quando necessário. Essa abordagem geralmente exige que cada URL receba uma variável GET separada para envio. Esta variável GET pode ser considerada um design mais simplificado que substitui o nome do script. Por exemplo:
http://example.org/dispatch.php?task=print_formdispatch.php é o único arquivo raiz (raiz do documento). Ele permite que os desenvolvedores façam duas coisas muito importantes:
implementar algum processamento de segurança global no dispatch.php no início e garantir que esse processamento não possa ser ignorado.
É fácil determinar onde a filtragem de dados é necessária, especialmente para algumas operações de fluxo de controle para fins especiais.
Veja o exemplo a seguir para uma discussão mais detalhada do script dispatch.php:
<?php/* Global Security Handling*/switch ($_GET['task']){case 'print_form':include '/inc/presentation/form.inc '; break;case 'process_form':$form_valid = false;include '/inc/logic/process.inc';if ($form_valid){include '/inc/presentation/end.inc';}else{include '/ inc/ apresentação/form.inc';}break;default:include '/inc/presentation/index.inc';break;}?>Se este for o único script PHP acessível publicamente, você pode ter certeza de que este programa O design garante que o processamento inicial de segurança global não possa ser ignorado. Também torna mais fácil para os desenvolvedores verem o fluxo de controle de tarefas específicas. Por exemplo, é fácil saber sem navegar por todo o código: quando $form_valid é verdadeiro, end.inc é o único exibido ao usuário, pois é antes de process.inc ser incluído e acabou de ser inicializado como falso; pode ser determinado que a lógica interna do process.inc o definirá como verdadeiro, caso contrário o formulário será exibido novamente (possivelmente com uma mensagem de erro associada).
Observe que se você usar um arquivo de diretiva de diretório como index.php (em vez de dispatch.php), poderá usar o endereço URL como este: http://example.org/?task=print_form .
Você também pode usar o redirecionamento ApacheForceType ou mod_rewrite para ajustar o endereço URL: http://example.org/app/print-form .
Outra forma de incluir métodos é usar um único módulo que seja responsável por todo o tratamento da segurança. Este módulo está incluído na frente (ou bem na frente) de todos os scripts PHP públicos. Consulte o seguinte script security.inc
<?phpswitch ($_POST['form']){case 'login':$allowed = array();$allowed[] = 'form';$allowed[] = 'username' ; $allowed[] = 'password';$sent = array_keys($_POST);if ($allowed == $sent){include '/inc/logic/process.inc';}break;}?>Neste caso , considera-se que cada formulário enviado contém o valor de verificação exclusivo do formulário e security.inc processa independentemente os dados no formulário que precisa ser filtrado. O formulário HTML que implementa esse requisito é o seguinte:
<form action="/receive.php" method="POST"><input type="hidden" name="form" value="login" /><p>Nome de usuário : <input type="text" name="username" /></p><p>Senha:<input type="password" name="password" /></p><input type="submit" / > </form>Um array chamado $allowed é usado para verificar quais variáveis do formulário são permitidas. Esta lista deve ser consistente antes do formulário ser processado. O controle do processo decide o que executar, e process.inc é onde os dados filtrados reais chegam.
Observe que a melhor maneira de garantir que security.inc seja sempre incluído no início de cada script é usar a configuração auto_prepend_file.
Exemplo de filtragem A criação de uma lista de permissões é muito importante para a filtragem de dados. Como é impossível dar exemplos para todos os dados de formulário que você encontrar, alguns exemplos podem ajudá-lo a obter uma compreensão geral.
O código a seguir valida o endereço de e-mail:
<?php$clean = array();$email_pattern = '/^[^@s<&>]+@([-a-z0-9]+.) +[ az]{2,}$/i';if (preg_match($email_pattern, $_POST['email'])){$clean['email'] = $_POST['email'];}?> abaixo O código garante que o conteúdo de $_POST['color'] seja vermelho, verde ou azul:
<?php$clean = array();switch ($_POST['color']){case 'red':case 'green ' :case 'blue':$clean['color'] = $_POST['color'];break;}?>O código a seguir garante que $_POST['num'] seja um número inteiro:
<?php$ clean = array ();if ($_POST['num'] == strval(intval($_POST['num']))){$clean['num'] = $_POST['num'];} >O seguinte? o código garante que $_POST['num'] seja um float:
<?php$clean = array();if ($_POST['num'] == strval(floatval($_POST['num ']))){ $clean['num'] = $_POST['num'];}?> Cada exemplo usa o array $clean antes da conversão do nome. Esta é uma boa prática para os desenvolvedores determinarem se seus dados estão potencialmente comprometidos. Nunca salve dados em $_POST ou $_GET após validá-los. Como desenvolvedor, você deve sempre suspeitar totalmente de dados salvos em arrays superglobais.
Vale acrescentar que usar $clean pode ajudar a pensar no que não foi filtrado, o que é mais parecido com o papel de uma whitelist. Pode melhorar o nível de segurança.
Se você armazenar apenas dados validados em $clean, o único risco na validação de dados é que o elemento da matriz que você está referenciando não exista, e não dados perigosos não filtrados.
Tempo Assim que o script PHP começar a ser executado, significa que todas as solicitações HTTP foram encerradas. Neste ponto, o usuário não tem chance de enviar dados para o script. Portanto, nenhum dado pode ser inserido no script (mesmo se register_globals estiver ativado). É por isso que inicializar variáveis é uma prática muito boa.