Aplicativos em PHP/Apêndices/Segurança: diferenças entre revisões

[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
Ribafs (discussão | contribs)
Sem resumo de edição
Ribafs (discussão | contribs)
Sem resumo de edição
Linha 62:
Em primeiro lugar devemos atentar para uma boa análise e projeto da aplicação. Da qualidade destes depende a qualidade da aplicação. Então devemos planejar o banco de dados cuidadosamente: tabelas, relacionamentos, campos, tipos de dados, etc. Mais importantes ainda em termos de segurança é a criação de usuários que tenham acesso somente ao aplicativo e com privilégios somente para suas operações com nomes e senhas seguras, como também usuários do banco com respectivas permissões e permissões do sistema operacional.
 
As aplicações Web contam com formas populares de acesso global a dados, a serviços e a produtos. Enquanto este acesso global é uma das grandes vantagens da Web, qualquer regra de segurança nesses aplicativos também é globalmente exposta e freqüentemente explorada.
É muito fácil escrever aplicações que contém regras de segurança. Vide aplicações famosas como phpMyAdmin, PHPShop e FreeTrade.
 
Algumas Recomendações a favor da Segurança
 
- Evitar uso de Variáveis quando acessando Arquivos
 
Cuidado com as funções:
 
- readfile
 
- fopen
 
- file
 
- include
 
- require
 
 
Caso decida assim mesmo utilizar, tome precauções. Uma boa precaução é que o valor das variáveis seja definido com o uso da função “define”, garantindo que seu conteúdo seja conhecido e testado.
Caso decida assim mesmo utilizar, tome precauções. Uma boa precaução é que o valor das variáveis seja definido com o uso da função "define", garantindo que seu conteúdo seja conhecido e testado.
 
- Checar os nomes dos arquivos em uma lista de nomes válidos. Veja um exemplo:
$valid_pages = array(
Linha 92 ⟶ 103:
}
 
- Use as configurações de variáveis “allow_url” e “open_basedir” para limitar as localizações de onde os arquivos podem ser abertos.
 
 
Utilizar Caracteres de Escape em Instruções SQL
 
// Usar a função para testar a existência de registro
if (record_exists($query)) {
Linha 102 ⟶ 115:
}
 
 
O uso da diretriz “magic_quotes_gpc” setada para On no php.ini insere caracteres de escape nas Super Globais $_POST, $_GET e COOKIES. Veja o exemplo abaixo do site oficial:
O uso da diretriz “magic_quotes_gpc” setada para On no php.ini insere caracteres de escape nas Super Globais $_POST, $_GET e COOKIES.
Veja o exemplo abaixo do site oficial:
 
<?php
echo get_magic_quotes_gpc(); // 1
Linha 117 ⟶ 133:
$sql = "INSERT INTO lastnames (lastname) VALUES ('$lastname')";
?>
 
 
Use addslashes e stripslashes, caso esteja usando variáveis globais (register_globals = On) e não esteja usando magic_quotes_gpc como no exemplo abaixo (adiciona antes de inserir no banco e remove antes de exibir na tela):
 
 
// Recebendo do Form
 
$thisCodigo_curso = addslashes($_REQUEST['thisCodigo_cursoField']);
$thisNome = addslashes($_REQUEST['thisNomeField']);
Linha 126 ⟶ 145:
$sqlQuery = "INSERT INTO curso (codigo_curso , nome )
VALUES ('$thisCodigo_curso' , '$thisNome' )";
 
 
// Enviando para a tela
Linha 138 ⟶ 158:
 
Obs.: O uso simultâneo de magic_quotes_gpc = On com addslashes e stripslashes gera problemas, assim como não podemos usar register_globals = On simultaneamente com as Super Globais $_POST, $_GET.
 
 
Caso esteja usando variáveis que espera números para seu conteúdo nas instruções SQL, esteja seguro de que realmente contém números. Existem diversas funções em PHP incluindo sprintf, ereg e is_long para realizar a checagem. Também podemos utilizar o JavaScript para checar as entradas logo no formulário.
 
 
- Não Confir em Variáveis Globais
 
 
Se register_globals = On no php.ini, então o PHP criará variáveis globais para cada requisição GET, POST e variáveis Cookie.
 
 
Preste bastante atenção nas seguintes áreas:
 
- Código de checagem de autenticação e permissão
 
- Uso de variáveis antes de serem inicializadas. (Podemos ajustar error_reporting para ser alertados sempre que se usar variáveis não inicializadas.
- Uso de variáveis antes de serem inicializadas. (Podemos ajustar error_reporting para ser alertados sempre que se usar
variáveis não inicializadas.
 
- Uso de variáveis designadas para ser usadas por requisições GET ou POST.
 
 
Veja da documentação oficial:
 
 
Exemplos error_reporting()
 
<?php
 
Linha 176 ⟶ 207:
 
?>
 
 
Possíveis Correções e Melhorias
 
 
Desabilitar “register_globals” no php.ini. Após esta mudança somente podemos acessar entradas de formulários usando $_POST ou $_GET. Fica mais trabalhoso um pouco mas bem mais seguro (vale a pena).
 
 
Cuidado com o recurso “Esqueceu a Senha” de formulários de Login.
 
 
Escreva código para inicializar todas as variáveis globais.
 
 
Evite Falsos Uploads
 
 
Examine todos os scripts que respondem a upload de arquivos.
 
 
Use as funções is_uploaded_file e move_upload_file que permitem ao programador estar seguro de que está trabalhando com os devidos arquivos enviados.
 
 
Caso não tenha certeza de estar rodando em uma versão atual do PHP, configure upload_tmp_dir que executa checagem de entrada que o arquivo que estamos trabalhando está neste diretório.
 
 
Idéias Adicionais
 
 
- Encripte ou use hashes de senhas quando armazenando. A função md5 é útil para isso.
 
Exemplo retirado do www.phpbrasil.com:
 
 
//BY ADEMIR BATISTA PEREIRA
Linha 266 ⟶ 308:
 
Force senhas seguras. No mínimo exija senhas com 8 caracteres de tamanho e que contenham algum caractere não alfanumérico.
 
 
Avoid SQL injection
 
This is a function which will format the passed string depending of it's specified to be a number or a string, in order to avoid problems with SQL injections in scripts.
 
Type: code fragment
 
Version:
 
Requires:
 
Added by: bto (email author)
 
Entered: 19/08/2004
 
Last modified: 08/12/2003
 
Rating - (fewer than 3 votes)
 
Views 3024
 
<?php
function ToDBString($string, $link, $isNumber=false)
Linha 307 ⟶ 360:
}
?>
 
Example
 
$link=mysql_db_connect("HOST", "USER", "PASSWORD");
 
Linha 316 ⟶ 371:
 
//If $_POST["foo"] or $_POST["bar"] are a string of this kind: "'' OR 1=1" and we don't use ToDBString we will show all the info of the table!!!!
 
 
- Usar sempre extensões tipo PHP em todos os scripts.
 
Nunca usar extensões .inc, .class, etc. Podemos usar assim: nome.inc.php.
 
 
Arquivos com extensões .inc, .class e similares ao serem abertos no browser exibem todo o seu conteúdo, inclusive senhas de banco, trechos de código PHP e outras, já script .php, antes de serem abertos no browser são processados pelo servidor web e só chega ao browser o resultado em HTML.
 
 
Não insira Conteúdo Sigiloso no raiz do Aplicativo
 
Imagens de proteção de senha, documentos e outras imagens devem ficar fora do raiz do aplicativo.
 
Alternativamente armazene no banco de dados.
 
Proteger os diretórios usando características do Apache, como arquivos .htaccess, que previnem o acesso direto ao conteúdo dos diretórios.
 
 
Muita atenção aos Serviços de Hospedagem
'''Muita atenção aos Serviços de Hospedagem'''
 
Estes servidores compartilham suas máquinas com diversos usuários, que têm acesso aos arquivos. Como também podem criar um arquivo de session (que armazena em /tmp por default), que pode conter maliciosos users e senhas para bypassar sua autenticação.
 
 
Verifique sempre as informações do PHP (phpinfo()) do servidor, caso use esses serviços.
 
 
Idealmente use um servidor dedicado ao invés.
 
 
Assegure-se de que o servidor ative safe_mode no php.ini.
 
 
As permissões dos arquivos são outro ponto importante. Devem somente ser lidos pelo web Server. No UNIX use algo como 711.
 
 
Use sempre validações para garantir que os usuários realmente entram com informações válidas.
Linha 344 ⟶ 413:
Fuja ou Evite Entrada de Usuários quando Construindo Comandos de Strings
Funções como exec e eval são muito flexíveis mas requerem muito cuidado, pois os usuários podem entrar com comandos inesperados.
 
 
Evite ao máximo as funções:
 
- eval
 
• preg_replace (quando usada com /e deve interpretar parâmetros como código PHP)
- preg_replace (quando usada com /e deve interpretar parâmetros como código PHP)
• exec
 
• passthru
- exec
• system
 
• popen
- passthru
• ` ` (pode ser usado para executar comandos)
 
- system
 
- popen
 
- (pode ser usado para executar comandos)
 
 
Além do Código (Um projeto de segurança forte)
 
 
Projeto de Aplicação Segura
 
- Considere o uso do HTTPS para encriptar transmissões.
 
- Considere restringir acesso aos diretórios usando .htaccess do Apache. Checar através das variáveis de ambiente do PHP, como $REMOTE_ADDR
 
- Usar pacotes de segurança existentes, como o PHPLib.
 
 
Todas as linguagens tem seus pontos fracos, mas tomando diversos cuidados preventivos e atentando para as boas regras de segurança, estes pontos podem ser protegidos. Seguindo os passos mostrados aqui podemos desenvolver um código mais seguro que o usual.
Linha 366 ⟶ 448:
 
Um dos mais importantes conceitos a se ter em mente em termos de segurança é o de nunca confiar que o usuário irá digitar exatamente o que se espera que ele digite.
 
 
- Nunca inclua, requeira ou abra um arquivo cujo nome seja baseado em entrada do usuário, sem antes checar.
 
 
- Seja muito cuidados quando usando “register_globals = On”.
 
Isso foi feito para tornar o uso do PHP algo fácil, o que realmente aconteceu. Mas em contrapartida trouxe sérios problemas de segurança. A partir da versão 4.2.0 este parâmetro já vem setado como Off por default. Neste caso para pegar o valor de variáveis lançadas pelo formulário devemos utilizar as superglobais $_POST, $_GET, $_REQUEST, $_COOKIE. Ou $_SESSION.
 
 
O recomendado é que se trabalhe com “register_globals = Off”.
 
 
Usando “error_reporting = E_ALL” no php.ini recebemos uma notificação sempre que tentarmos chamar variáveis que ainda não tenham sido definida. Sabemos que o PHP não exige a definição de variáveis, mas recomenda-se que nos acostumemos a definir todas as variáveis e inclusive a iniciá-las, em termos de segurança.
 
 
- Nunca execute consultas a bancos sem usar funções de escape.
 
 
O PHP traz ativa por default, uma proteção contra a entrada de caracteres especiais nos formulários, que é o “magic_quotes_gpc = On”.
 
 
- Nunca confie em dados de fontes externas.
 
 
- Toda entrada de usuário deve ser validada e formatada para garantir a segurança.
Linha 386 ⟶ 477:
 
Protegendo Arquivos e Diretórios com .htaccess via Apache
 
 
- Para ativar o .htaccess em todo o servidor web, edite o httpd.conf e adicione:
Linha 393 ⟶ 485:
AllowOverride AuthConfig
</Directory>
 
 
- Então criamos o arquivo .htaccess existente no diretório raiz e adicionamos tags de acordo com nossos propósitos. Exemplos:
 
 
- Restringindo o acesso por IP/Host
 
# Deixa a Intranet acessar
 
Order allow,deny
allow from 192.168.0.
Linha 403 ⟶ 499:
 
Ou
 
# Deixa todo mundo acessar, menos o IP 192.168.0.25
 
Order deny,allow
deny from 192.168.0.25
allow from all
 
 
- Restringindo o acesso por user/senha
 
$ mkdir /etc/httpd/auth
 
$ cd /etc/httpd/auth
 
 
$ htpasswd -c acesso hugo
 
New password:
 
Re-type new password:
 
Adding password for user hugo
 
 
$ htpasswd acesso eitch
 
New password:
 
Re-type new password:
 
Adding password for user eitch
 
 
$ htpasswd acesso sakura
 
New password:
 
Re-type new password:
 
Adding password for user sakura
 
- Agora criar o .htaccess:
 
AuthName "Acesso Restrito à Usuários"
 
AuthType Basic
 
AuthUserFile /etc/httpd/auth/acesso
 
require valid-user
 
 
AuthUserFile /etc/httpd/auth/acesso – onde estão as senhas e users.
 
 
- Opções para arquivos e diretórios específicos:
 
# Restringe o arquivo_secreto.html somente para o IP 192.168.0.30
<Files arquivo_secreto.html>
Linha 441 ⟶ 562:
Deny from all
</Files>
 
 
# Restringe o diretório admin para utilizar senhas
 
<Directory /admin>
AuthName "Acesso Restrito à Usuários"
Linha 450 ⟶ 573:
require group admin
</Directory>
 
 
# Nega o acesso dos clientes ao .htaccess (bom colocar no httpd.conf)
Linha 460 ⟶ 584:
 
 
'''Prevenindo Injeções SQL'''
 
Uma Função para prevenir tais injeções.
 
Esta é uma função que deve formatar a string passada dependendo de se foi especificado um número ou uma string, para evitar o problema com injeções SQL em scripts.
 
Autor: bto (no site
 
Linha 496 ⟶ 622:
}
?>
 
 
Example
 
$link=mysql_db_connect("HOST", "USER", "PASSWORD");
 
Linha 507 ⟶ 635:
//If $_POST["foo"] or $_POST["bar"] are a string of this kind: "'' OR 1=1" and we don't use ToDBString we will show all the info of the table!!!!
 
 
Referências:
'''Referências:'''
 
1 – http://www.onlamp.com/lpt/a/3305 - Ten Security Checks for PHP
 
2 - http://www.onlamp.com/lpt/a/4045 - PHP Security
 
3 - http://www.devshed.com/c/a/PHP/PHP-Security-Mistakes/ - PHP Security Mistakes
 
4 - http://www.devin.com.br/eitch/htaccess/ - Uso e Segurança com o .htaccess
 
5 - http://www.securiteam.com/securityreviews/5DP0N1P76E.html - SQL injeções
 
6 - http://www.zend.com/codex.php?id=1405&single=1 - SQL injeções
 
7 – http://www.imasters.com.br/imprimir.php?cn=292&cc=44
 
8 – http://www.imasters.com.br/imprimir.php?cn=293&cc=44
 
9 – http://www.imasters.com.br/imprimir.php?cn=319&cc=44