Posts Categorizados ‘Segurança

28
Abr
09

Como fazer o seu script php solicitar autenticação usando header

28
Abr
09

How to install mod evasive, como instalar o mod evasive

22
Fev
09

Evento: II encontro PHP-PB

O que é?

O segundo encontro do grupo de desenvolvedores PHP da Paraíba tem como objetivo reunir os membros do grupo, estudantes e profissionais da área de TI para troca de conhecimentos na tecnologia PHP e relacionadas. O encontro contará com palestras e momentos de networking entre os participantes.

Se você não participou do primeiro enconto, veja como foi:

* Fotos
* Apresentações

Quando?

Dia 07 de Março de 2009, a partir das 8 da manhã na Unipê, localizada na BR-230, bairro Água Fria em João Pessoa.
Unipê

Quer patrocinar?

Faça já o download do nosso plano de patrocínio e entre em contato conosco!

Inscrições

A participação no evento é gratuita, porém é necessária a prévia inscrição e a doação de 1Kg de alimento não perecível no dia do evento.

A doação será repassada à Casa da Criança com Câncer, instituição filantrópica que dá apoio aos pacientes e familiares vindos do interior em busca de tratamento no Hospital do Câncer Napoleão Laureano.

Os membros inscritos e presentes no dia do evento concorrerão a diversos brindes como livros da editora O’Reilly, camisetas, um elePHPant de pelúcia e muito mais!

Já contamos com 378 inscritos no total, sendo 1 só nas últimas 24 horas!

Inscreva-se AQUI!

Fonte: http://www.nerdblog.info/2009/02/22/ii-encontro-php-pb/

22
Fev
09

Tutorial de segurança em aplicações PHP (parte 1)

Estou anotando algumas dicas para aumentar a segurança em aplicações php (linguagem a qual programo).
Abaixo irei colocar algumas dicas sobre o que tenho aprendido, mas infelizmente de maneira resumida, definida como parte 1:

-alertas de erro -> Desabilitado (coisas como error_reporting(E_ALL);) – isto só pode ocorrer em um sistema no momento de testing.
-register_globals -> Desabilitado
-permissão ->dar o mínimo de privilégios possível no sistema, a nível
de bd e etc.
-variáveis ->setar vazios antes de atribuir strings.

Ex:

<?php

$busca = ”;

if (isset($_GET['busca']))

{

$busca = $_GET['busca'];

}

?>
- usar ssl para dados importantes, evitando exposição de dados.
- Forçar a segurança de maneira que não pese ao usuário,
se possível transparente. Ex: solicitar autenticação por medida de segurança para um transação importante de um cliente já autenticado no sistema.

- tomar sempre cuidado no ato de detecção de ataques, isso pode impedir a usabilidade do sistema.
- cuidados com interações em sistemas remotos (rss, apis remotas – web services).
- filtrar bem os dados (todos) que entram, para não operar com dados
maliciosos.

Filtrar dados é ler o que se entra por $ _GET e $ _POST e observar o que está malicioso e distinguir isto. (bem fácil de filtrar, ruim é identificar a origem)

Todas entradas têm de vir de uma fonte remota, se você não conhece as entradas, não pode se defender delas.

Entradas como $_SERVER exigem muito mais trabalho na hora da filtragem.
- A pior forma de filtrar é tentar manipular ao invés de tratar que o que é limpo é limpo e o que é sujo é sujo, do contrário, tentar manipular as informações poderá criar brechas.
Trecho que reforça a segurança quando um atacante tenta retroceder 1 diretório (ou mais):

<?php

$nomefile = $_POST['nomefile'];

while (strpos($_POST['nomefile'], ‘..’) !== FALSE)
{
$nomefile = str_replace(‘..’, ‘.’, $nomefile);
}

?>

Evidentemente, o basename() função pode substituir toda esta técnica e é uma maneira segura de atingir o objectivo pretendido. O ponto importante é que qualquer tentativa de corrigir Dados inválidos podem conter um erro e permitir a passagem de dados inválidos. Inspeção é uma alternativa muito mais seguro.

INSPECIONAR É MELHOR QUE CORRIGIR, quando se tenta corrigir geralmente se abre uma falha, o que é a real necessidade do atacante.

Se você consegue identificar com precisão e fidelidade a entrada dos dados você já fez quase tudo.
Após, o passo seguinte é criar um filtro fiel para distinguir dados ruins de dados bons.

sempre que for tratar dados o bom é criar um array vazio e atribuir dados a ele, que você realmente sabe que estão limpos.

<?php
$limpo = array( );
switch($_POST['cor']) {
case ‘vermelho’:
case ‘verde’:
case ‘azul’:
$limpo['cor'] = $_POST['cor'];
break;
}
?>

Estamos garantindo mais segurança por que a cor só pode ser uma das três e nada mais, neste caso!

você pode querer afirmar que um usuário só pode conter caracteres alfanuméricos:

<? php

$limpo = array ();

if (ctype_alnum ($ _POST [ 'user']))
(
$limpo[ 'user'] = $ _POST [ 'user'];
)

?>

Procure sempre usar funções nativas do php para segurança, isto pode lhe prevenir de problemas como erro de lógica, resultando assim em uma
brecha de segurança (o que um atacante necessita).

Para ajudar na segurança nos devemos:

Identificar saída,

Escapar saída,

Distinção entre escapara e não escapar dados .

É importante para escapar apenas dados filtrados. Embora escapar sozinho pode evitar muitas das vulnerabilidades de segurança, não deve nunca ser considerado como um substituto para a filtragem de entrada. Dados maliciosos devem ser filtrados primeiro e depois escapados.

Filtrar as entradas com htmlentities é melhor que htmlspecialchars, mas ambas são boas para converter o que vem da web, um exemplo legal é este aqui:

<?php
$htm = array( );
$htm['user'] = htmlentities($limpo['user'], ENT_QUOTES, ‘UTF-8′);
echo “<p>Olá, {$htm['user']}.</p>”; ?>

Isso garante a entrada de dados do user, e de tabela quebra a forma em que os dados vêm de maneira a traduzir caracteres “malucos” em html.

Devemos escapar todos os dados SIM, isto ajuda na segurança de sua aplicação.
htmlentities não converte caracteres alfanuméricos, mas previne que dados estranhos operem em interação do usuário com o sistema.

Outra política, voltando-se ao famoso e muito utilizado mysql é usar funções nativas para escapar entradas de dados para o banco de dados.
Usamos a função mysql_real_escape_string ().
Podemos usar também addslashes para ajudar na relação com o mysql, mas em última instância.

<?php $mysql = array( );

$mysql['username'] = mysql_real_escape_string($clean['username']);

$sql = “SELECT * FROM profile WHERE username = ‘{$mysql['username']}’”; $result = mysql_query($sql); ?>

Fonte -> http://phpsecurity.org/

17
Dez
08

Detecção de Intrusos em Aplicações WEB PHP com PHPIDS

Detecção de Intrusos em Aplicações php com PHPIDS

A dica aqui vai para servidores que rodam com o apache e php5 (sob linux).
O PHPIDs é um sistema de detecção de instrusos, simples, rápido, bem estruturado e de fácil utilização. Isto cria mais uma camada de segurança para a sua aplicação web. Ele não vai filtrar entradas maliciosas, tampouco fazer maravilhas, como se estivesse com inteligência artificial, ele irá detectar o ataque e irá reagir segundo as suas configurações. O interessante é que ele tem o poder de decisão no momento de uma tentativa de invasão. Ele
pode servir para informar ao atacante que está tentando invadir de cuidade, alerta e etc, ou mesmo, notificar ao core de desenvolvimento da aplicação por email a tal tentativa de invasão.

Este how to é beta e nada aqui é GARANTIDO de funcionar, mas deve!

Requerimentos:

Os testes foram realizados na plataforma Gnu/Linux, no sabor Debian Etch, o qual teve ip

setado como 192.168.0.100, tendo por usuário e grupo de usuário do apache www-data.
Nos testes o diretório principal usado é um virtual host -> /var/www/web1/web

Por questões de segurança o diretório do PHPIDs será criado em outro lugar para evitar problemas com a estrutura, tornando-a mais difícil contra vulnerabilidade, no caso:

mkdir /var/www/web1/phpids

Criamos um diretório recursivo, evitando acesso público ao web, que deixaria o script vulnerável.

O arquivo que usamos neste tutorial é phpids-0.4.7.tar.gz, o qual temos apenas a necessidade de uso diretório lib.

cd /tmp
wget http://php-ids.org/files/phpids-0.4.7.tar.gz
tar xvfz phpids-0.4.7.tar.gz
cd phpids-0.4.7
mv lib/ /var/www/web1/phpids/

Agora mudamos o diretório para /var/www/web1/phpids/lib/IDS:

cd /var/www/web1/phpids/lib/IDS

Agora iremos fazer com que o /tmp permita escrita para o usuário do apache (log do phpids necessitará):

chown -R www-data:www-data tmp/

Agora vamos configurar o PHPIDs em seu arquivo de configuração:

cd Config/
vi Config.ini

As configurações são padrão, todavia iremos alterar o caminho de onde estão os arquivos, sendo o ajuste final idêntico a isto aqui:

; PHPIDS Config.ini

; General configuration settings

; !!!DO NOT PLACE THIS FILE INSIDE THE WEB-ROOT IF DATABASE CONNECTION DATA WAS ADDED!!!

[General]

filter_type     = xml
filter_path     = /var/www/web1/phpids/lib/IDS/default_filter.xml
tmp_path        = /var/www/web1/phpids/lib/IDS/tmp
scan_keys       = false

exceptions[]    = __utmz
exceptions[]    = __utmc

; If you use the PHPIDS logger you can define specific configuration here

[Logging]

; file logging
path            = /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt

; email logging

; note that enabling safemode you can prevent spam attempts,
; see documentation
recipients[]    = test@test.com.invalid
subject         = “PHPIDS detected an intrusion attempt!”
header                      = “From: <PHPIDS> info@php-ids.org”
safemode        = true
allowed_rate    = 15

; database logging

wrapper         = “mysql:host=localhost;port=3306;dbname=phpids”
user            = phpids_user
password        = 123456
table           = intrusions

; If you would like to use other methods than file caching you can configure them here

[Caching]

; caching:      session|file|database|memcached|none
caching         = file
expiration_time = 600

; file cache
path            = /var/www/web1/phpids/lib/IDS/tmp/default_filter.cache

; database cache
wrapper         = “mysql:host=localhost;port=3306;dbname=phpids”
user            = phpids_user
password        = 123456
table           = cache

; memcached
;host           = localhost
;port           = 11211
;key_prefix     = PHPIDS
;tmp_path       = /var/www/web1/phpids/lib/IDS/tmp/memcache.timestamp

Pronto, terminado.

Usando o PHPIDs

Nós iremos criar o arquivo que vai fazer a chamada do PHPIDs (depois iremos ajustar o arquivo para chamar automaticamente os recursos do PHPIDs para todas as contas do servidor):

<?php
set_include_path(
get_include_path()
. PATH_SEPARATOR
. ‘/var/www/web1/phpids/lib’
);

require_once ‘IDS/Init.php’;
$request = array(
‘REQUEST’ => $_REQUEST,
‘GET’ => $_GET,
‘POST’ => $_POST,
‘COOKIE’ => $_COOKIE
);
$init = IDS_Init::init(‘/var/www/web1/phpids/lib/IDS/Config/Config.ini’);
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();

if (!$result->isEmpty()) {
// Take a look at the result object
echo $result;
require_once ‘IDS/Log/File.php’;
require_once ‘IDS/Log/Composite.php’;

$compositeLog = new IDS_Log_Composite();
$compositeLog->addLogger(IDS_Log_File::getInstance($init));
$compositeLog->execute($result);
}
?>

Se você chamar o arquivo no browser, perceberá que o mesmo ficará em branco, no caso http://192.168.0.100/phpids.php – porém, mas se você tentar usar um suposto ataque, nosso amigo PHPIDs vai entrar em ação, use o exemplo -> http://192.168.0.100/phpids.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E

Pronto, agora iremos ver o caminho para que os scripts usem o PHPIDs, e o interessante aqui, você não precisará alterar todos os seus scripts, isto por que iremos chamar o script automaticamente como recurso do PHP, isto carregará o mesmo “como se fosse um módulo”, e o parâmetro que define isto bacaninha é -> auto_prepend_file, iremos apontar o arquivo no php.ini principal do servidor, isso dará força e velocidade no desenvolvimento usando tal recurso. Isto também pode ser feito em um arquivo .htaccess, desde que apontemos tudo corretamente, haverá de funcionar turbinado.

NO CASO DO PHP.INI

vi /etc/php5/apache2/php.ini

procure pela linha auto_prepend_file, se não achar, insira no meio do arquivo aberto:

auto_prepend_file = /var/www/web1/web/phpids.php

Reinicie o Apache:

/etc/init.d/apache2 restart

NO CASO DO ARQUIVO .HTACCESS

vi /var/www/web1/web/.htaccess

php_value auto_prepend_file /var/www/web1/web/phpids.php

Verifique os confs de vhost, se estão assim:

<Directory /var/www/web1/web/>
AllowOverride All
</Directory>

Caso sim, caso tenha mudado algo no apache e retorne para este padrão acima, reinicie o apache.

Crie um simples arquivo ->

vi /var/www/web1/web/info.php
dentro dele:

<?php
phpinfo();
?>

Faça um acesso simples -> http://192.168.0.100/info.php

Agora, para ver o PHPIDs em ação use http://192.168.0.100/info.php?test=%22%3EXXX%3Cscript%3Ealert(1)%3C/script%3E

Se as mensagens de alerta forem vistas é por que o script de /var/www/web1/web/phpids.php foi chamado automaticamente de dentro de /var/www/web1/web/info.php.

Sobre os logs

Podem ser vistos em /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt, para ver rapidamente o teste use:

cat /var/www/web1/phpids/lib/IDS/tmp/phpids_log.txt

Algo parecido com os termos abaixo será exibido:

“192.168.0.77″,2008-06-04T17:36:08+02:00,54,”xss csrf id rfe

lfi”,”REQUEST.test=%5C%22%3EXXX%3Cscript%3Ealert%281%29%3C%2Fscript%3E GET.test=%5C%22%3EXXX%3Cscript%3Ealert%281%29%3C%2Fscript%3E”,”%2Finfo.php%3Ftest%3D%2522%253EXXX%253Cscript%253Ealert%281%29%253C%2Fscript%253E”

Isso é bom para quem quer analisar tipos de ataques e quer reaplicar mudanças valiosas na segurança.

Vamos fazer uma mudança no nível de segurança para que seja exibida informação, caso esteja vazio o ataque, prossiga, do contrário será parado o script!

vi /var/www/web1/web/phpids.php

<?php
set_include_path(
get_include_path()
. PATH_SEPARATOR
. ‘/var/www/web1/phpids/lib’
);

require_once ‘IDS/Init.php’;
$request = array(
‘REQUEST’ => $_REQUEST,
‘GET’ => $_GET,
‘POST’ => $_POST,
‘COOKIE’ => $_COOKIE
);
$init = IDS_Init::init(‘/var/www/web1/phpids/lib/IDS/Config/Config.ini’);
$ids = new IDS_Monitor($request, $init);
$result = $ids->run();

if (!$result->isEmpty()) {
// Take a look at the result object
echo $result;
require_once ‘IDS/Log/File.php’;
require_once ‘IDS/Log/Composite.php’;

$compositeLog = new IDS_Log_Composite();
$compositeLog->addLogger(IDS_Log_File::getInstance($init));
$compositeLog->execute($result);

die(‘<h1>Go away!</h1>’);
}
?>

fonte:

http://www.howtoforge.com/intrusion-detection-for-php-applications-with-phpids

12
Ago
08

Combatendo envio de spam em scripts PHP

Insira sempre o código abaixo no início de seus scripts com forms:

// Proteção contra injeção de SPAM
foreach ($_POST as $j =>$value) {
if (stristr($value,”Content-Type”)) {
header(“HTTP/1.0 403 Forbidden”);
exit;
}
}

Este também:

// Mais uma proteção contra SPAM
if ( preg_match( “/bcc:|Content-Type:/i”, implode( $_POST ) ) ){ exit; }


Também valide entradas de email com expressão regular:

// Verificando se o email é válido
if  (!eregi(“^[_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3}$”, $_POST['email'])) {
die(“email inválido”);
}

É isso!




a