Este site usa cookies e tecnologias afins que nos ajudam a oferecer uma melhor experiência. Ao clicar no botão "Aceitar" ou continuar sua navegação você concorda com o uso de cookies.

Aceitar
Melhores Práticas de Segurança no Django

django

Melhores Práticas de Segurança no Django

Elias
Escrito por Elias
Junte-se a mais de X pessoas

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

A segurança de aplicações web não é opcional. Não adianta você construir uma aplicação Django incrível se ela estiver cheia de brechas de segurança.

Afinal, não importa quão boa seja a experiência do usuário, se os dados dele vazarem ou a aplicação for derrubada por um ataque, você terá sérios problemas.

Em um mundo onde ataques de hackers estão se tornando cada vez mais comuns e sofisticados, garantir que sua aplicação esteja protegida contra vulnerabilidades é essencial.

O Django já vem com uma série de proteções embutidas que te ajudam a manter a aplicação segura. Mas, como com qualquer framework, a segurança também depende de como você implementa e configura seu projeto.

Pequenos deslizes na configuração podem abrir portas para problemas como SQL Injection, XSS (Cross-Site Scripting), CSRF (Cross-Site Request Forgery), entre outros.

Neste artigo, vamos explorar as melhores práticas de segurança para garantir que seu projeto Django esteja protegido contra as vulnerabilidades mais comuns. Vamos abordar desde configurações básicas no arquivo settings.py, até medidas mais avançadas, como a implementação de autenticação multifator (2FA) e o uso de HTTPS.

Proteção Contra CSRF (Cross-Site Request Forgery)

Se você já mexeu com Django, provavelmente já ouviu falar do CSRF. O Cross-Site Request Forgery é um tipo de ataque onde um usuário mal-intencionado tenta executar ações em nome de outro usuário, sem o seu conhecimento.

O Django lida com isso usando tokens CSRF, que basicamente garantem que o formulário enviado foi realmente gerado pela aplicação.

Como o Django protege contra CSRF

Por padrão, o Django já aplica proteção contra CSRF em todas as requisições POST. Isso é feito automaticamente para todas as views que envolvem formulários. O framework insere um token CSRF em cada formulário e valida esse token quando o formulário é enviado.

Aqui está um exemplo básico de como um formulário protegido por CSRF se parece:

<form method="post">
    {% csrf_token %}
    <input type="text" name="username" placeholder="Nome de usuário">
    <input type="submit" value="Enviar">
</form>
Python

A mágica acontece com o {% csrf_token %}, que gera o token e garante que o formulário seja legítimo. Sem esse token, o Django irá rejeitar a requisição.

Configurando Proteção CSRF em APIs

Se você está construindo uma API RESTful, o CSRF pode não ser útil, já que a autenticação normalmente é feita via tokens ou outros métodos.

No entanto, caso sua API esteja lidando com requisições baseadas em cookies, é importante garantir que o CSRF esteja habilitado.

No Django Rest Framework, você pode usar o seguinte código para desativar CSRF apenas em views específicas:

from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
@api_view(['POST'])
def minha_view(request):
    return Response({"mensagem": "Esta view não requer CSRF"})
Python

Proteção Contra XSS (Cross-Site Scripting)

XSS, ou Cross-Site Scripting, é um tipo de ataque onde scripts maliciosos são injetados em páginas web. Esses scripts podem roubar dados do usuário, como cookies de sessão, ou até mesmo modificar o conteúdo exibido.

Como o Django protege contra XSS

Felizmente, o Django automaticamente escapa o conteúdo exibido nas templates. Isso significa que, se você estiver exibindo dados que vêm de uma fonte externa (como entradas de um formulário), o Django impedirá que qualquer script malicioso seja executado. Aqui está um exemplo:

<p>{{ user_input }}</p>
Python

Se o user_input contiver algo como <script>alert('XSS');</script>, o Django o exibirá como texto, e não como código executável, prevenindo o ataque.

Evitando XSS em formulários

Se por algum motivo você precisar exibir dados sem escapar (o que raramente é necessário), o Django oferece a tag safe. No entanto, use com cuidado, pois você estará desativando a proteção:

<p>{{ user_input|safe }}</p>
Python

Uma boa prática é evitar o uso de safe, a menos que você tenha certeza absoluta de que o dado que está exibindo é seguro.

Proteção Contra SQL Injection

O famoso SQL Injection é um dos ataques mais antigos, mas continua sendo um dos mais perigosos. Se um invasor conseguir injetar código SQL malicioso na sua aplicação, ele poderá obter acesso a dados sensíveis, modificar o banco de dados ou até mesmo derrubar sua aplicação.

Como o Django previne SQL Injection

O Django ORM já faz um ótimo trabalho protegendo sua aplicação contra SQL Injection, pois ele usa queries parametrizadas por padrão. Isso significa que você nunca precisa concatenar strings SQL manualmente, o que previne a injeção de código.

Veja um exemplo de uma query comum:

User.objects.filter(username='admin')
Python

O ORM do Django transforma essa query em uma instrução SQL segura, onde os valores são tratados como parâmetros e não como parte do código SQL. No entanto, se você estiver usando RawSQL, deve tomar cuidado extra.

Quando usar consultas SQL brutas

Se por algum motivo você precisar usar SQL bruto (e às vezes isso é inevitável), sempre use consultas parametrizadas:

from django.db import connection

def get_users_by_email(email):
    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM auth_user WHERE email = %s", [email])
        return cursor.fetchall
Python

Aqui, %s é o marcador de posição, e os valores são passados separadamente, prevenindo injeção de SQL.

Configurações de Segurança no settings.py

O arquivo settings.py é o coração da sua aplicação Django, e se configurado incorretamente, pode deixar sua aplicação exposta a vulnerabilidades. Aqui estão algumas configurações cruciais que você deve garantir que estejam configuradas corretamente.

Nunca deixe o DEBUG ativado em produção. Quando DEBUG = True, o Django exibe detalhes sobre erros diretamente no navegador, o que pode expor informações sensíveis sobre sua aplicação.

DEBUG = False
Python

ALLOWED_HOSTS

Essa configuração define quais domínios podem acessar sua aplicação. Não deixe isso em branco em produção ou com valor “*”. Adicione explicitamente os domínios autorizados:

ALLOWED_HOSTS = ['meusite.com', 'www.meusite.com']
Python

SECURE_SSL_REDIRECT

Sempre que possível, use HTTPS para garantir que os dados trocados entre o cliente e o servidor sejam criptografados. Para forçar o uso de HTTPS, ative SECURE_SSL_REDIRECT:

SECURE_SSL_REDIRECT = True
Python

SECURE_HSTS_SECONDS

Outra medida importante para garantir o uso de HTTPS é habilitar o HTTP Strict Transport Security (HSTS). Isso força os navegadores a sempre usar HTTPS para acessar sua aplicação:

SECURE_HSTS_SECONDS = 31536000  # Um ano
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
Python

SECURE_BROWSER_XSS_FILTER e X-Content-Type-Options

Essas duas configurações ajudam a prevenir ataques XSS e garantem que o navegador não execute código malicioso inadvertidamente:

SECURE_BROWSER_XSS_FILTER = True
X_CONTENT_TYPE_OPTIONS = 'nosniff'
Python

X-Frame-Options

Essa configuração impede que sua aplicação seja carregada em um iframe, prevenindo ataques de clickjacking:

X_FRAME_OPTIONS = 'DENY'
Python

Gerenciamento de Senhas e Autenticação

O gerenciamento de senhas e autenticação é uma parte crítica da segurança da sua aplicação Django. Aqui estão algumas boas práticas:

Usando um sistema seguro de armazenamento de senhas

O Django já vem configurado com algoritmos seguros para armazenar senhas. No entanto, você pode reforçar a segurança ajustando os hashers usados:

PASSWORD_HASHERS = [
    'django.contrib.auth.hashers.Argon2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
]
Python

Utilizando django-axes para limitar tentativas de login

O django-axes é uma excelente ferramenta para limitar o número de tentativas de login falhas e prevenir força bruta:

pip install django-axes
Python

Em seguida, adicione-o ao seu settings.py:

INSTALLED_APPS = [
    # Outros apps...
    'axes',
]

MIDDLEWARE = [
    # Outros middlewares...
    'axes.middleware.AxesMiddleware',
]

AXES_FAILURE_LIMIT = 5  # Número máximo de tentativas de login
Python

Autenticação multifator (2FA)

Implementar autenticação multifator é uma das maneiras mais seguras de proteger contas de usuários. Existem pacotes como o django-otp que facilitam a adição de 2FA ao Django:

pip install django-otp
Python

Após configurar o django-otp, você poderá adicionar um segundo fator de autenticação, como códigos temporários enviados por SMS ou aplicativos de autenticação.

Implementando HTTPS corretamente

Se você ainda não está usando HTTPS em sua aplicação Django, está correndo riscos desnecessários. O HTTPS garante que os dados transmitidos entre o cliente e o servidor sejam criptografados, prevenindo que terceiros interceptem informações sensíveis.

Certificados SSL

Hoje em dia, obter um certificado SSL é fácil, e você pode até usar o Let’s Encrypt, que oferece certificados SSL gratuitos. Aqui está um exemplo básico de como configurar o HTTPS em um servidor usando Nginx:

server {
    listen 443 ssl;
    server_name meusite.com;

    ssl_certificate /etc/letsencrypt/live/meusite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/meusite.com/privkey.pem;

    # Outros ajustes...
}
Python

Manutenção de Dependências e Pacotes de Terceiros

Muitas vulnerabilidades surgem de pacotes de terceiros desatualizados. Manter suas dependências atualizadas é uma das formas mais simples de garantir a segurança da sua aplicação.

Usando pip-audit para verificar vulnerabilidades

O pip-audit é uma ferramenta que varre suas dependências em busca de vulnerabilidades conhecidas. Para usá-lo, basta instalar:

pip install pip-audit
pip-audit
Python

Isso vai te dar uma lista de pacotes que precisam ser atualizados ou que possuem vulnerabilidades conhecidas.

Mantendo dependências atualizadas

Usar ferramentas como Dependabot para monitorar e atualizar automaticamente suas dependências é uma ótima prática. Isso garante que você sempre estará rodando versões seguras das bibliotecas de terceiros.

Controle de Acesso e Permissões

O controle de acesso correto é essencial para garantir que apenas usuários autorizados possam executar determinadas ações ou acessar recursos sensíveis.

Usando Decorators de Autenticação

O Django oferece decorators como @login_required e @permission_required para garantir que apenas usuários autenticados ou com as permissões necessárias possam acessar determinadas views:

from django.contrib.auth.decorators import login_required

@login_required
def minha_view_protegida(request):
    # Lógica da view
    pass
Python

Proteção de APIs REST

Se você está construindo uma API com o Django Rest Framework (DRF), certifique-se de usar as classes de permissão para controlar o acesso:

from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

class MinhaAPI(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({"mensagem": "Você está autenticado!"})
Python

Logs de Segurança e Monitoramento

Monitorar eventos de segurança e registrar logs detalhados sobre tentativas de ataque pode ajudar a identificar e prevenir problemas antes que eles se tornem graves.

Habilitando logs de segurança

No settings.py, configure o Django para registrar eventos de segurança em um arquivo de log:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/path/to/django_security.log',
        },
    },
    'loggers': {
        'django.security': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}
Python

Conclusão

A segurança de aplicações web deve ser tratada como uma prioridade, e isso não é diferente com projetos Django. Felizmente, o Django já vem com uma série de proteções embutidas que cobrem a maioria dos cenários de ataque mais comuns, mas cabe ao desenvolvedor garantir que essas ferramentas sejam usadas corretamente.

Neste artigo, cobrimos as principais vulnerabilidades que podem afetar um projeto Django, como CSRF, XSS, SQL Injection e falhas em permissões, além de abordarmos como configurar corretamente o arquivo settings.py para proteger a aplicação em produção.

A melhor abordagem para garantir que sua aplicação esteja segura é revisar constantemente o código, manter dependências atualizadas e estar sempre atento a novas vulnerabilidades que possam surgir. No final das contas, uma aplicação segura é aquela que permite que você durma tranquilo à noite, sabendo que seus usuários e dados estão protegidos.

E, claro, lembre-se: a segurança nunca é um trabalho concluído – é um processo contínuo.