<h2>Autenticação e Autorização: O Primeiro Pilar</h2>
<p>A segurança de uma API começa com a identificação correta de quem está acessando seus recursos. Autenticação valida a identidade do usuário, enquanto autorização define o que esse usuário pode fazer. Em projetos reais, JWT (JSON Web Tokens) é o padrão de facto, especialmente em arquiteturas distribuídas.</p>
<p>JWT funciona criando um token assinado que contém claims (dados) sobre o usuário. O servidor valida a assinatura sem precisar consultar um banco de dados a cada requisição. Implementar corretamente significa usar algoritmos robustos (RS256 ou ES256) e nunca deixar chaves secretas expostas.</p>
<pre><code class="language-python"># Exemplo com Flask e PyJWT
from flask import Flask, request, jsonify
from functools import wraps
import jwt
from datetime import datetime, timedelta
app = Flask(__name__)
app.config['SECRET_KEY'] = 'sua-chave-super-secreta-aqui'
def token_obrigatorio(f):
@wraps(f)
def decorador(args, *kwargs):
token = request.headers.get('Authorization', '').replace('Bearer ', '')
if not token:
return jsonify({'erro': 'Token ausente'}), 401
try:
payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
request.usuario_id = payload['usuario_id']
except jwt.InvalidTokenError:
return jsonify({'erro': 'Token inválido'}), 401
return f(args, *kwargs)
return decorador
@app.route('/login', methods=['POST'])
def login():
dados = request.get_json()
Validar credenciais contra banco de dados
usuario_id = 1 # Após validação real
token = jwt.encode({
'usuario_id': usuario_id,
'exp': datetime.utcnow() + timedelta(hours=1)
}, app.config['SECRET_KEY'], algorithm='HS256')
return jsonify({'token': token})
@app.route('/dados-protegidos', methods=['GET'])
@token_obrigatorio
def dados_protegidos():
return jsonify({'mensagem': f'Dados do usuário {request.usuario_id}'})</code></pre>
<p>Para autorização granular, implemente roles e permissões no token. Nunca confie apenas no ID do usuário vindo da requisição; sempre valide contra o token decodificado.</p>
<h2>Proteção de Dados em Trânsito e Armazenamento</h2>
<p>Dados viajando pela rede devem ser criptografados. HTTPS é mandatório — não é negociável em produção. TLS 1.2 ou superior protege contra interceptação, mas você também precisa se preocupar com o que acontece quando os dados chegam ao servidor.</p>
<p>Senhas nunca devem ser armazenadas em texto plano. Use bcrypt, Argon2 ou PBKDF2. Para dados sensíveis (números de cartão, tokens), considere criptografia em repouso com AES-256. Implementar corretamente significa não reinventar a roda — use bibliotecas testadas.</p>
<pre><code class="language-python"># Exemplo com bcrypt para senhas
from bcrypt import hashpw, gensalt, checkpw
from cryptography.fernet import Fernet
import os
Armazenar senha
def registrar_usuario(email, senha):
salt = gensalt(rounds=12)
senha_hash = hashpw(senha.encode(), salt)
Salvar no banco: INSERT INTO usuarios (email, senha) VALUES (email, senha_hash)
return senha_hash
Validar senha
def validar_login(email, senha):
senha_bd = SELECT senha FROM usuarios WHERE email = email
return checkpw(senha.encode(), senha_bd)
Criptografar dados sensíveis
def criptografar_cartao(numero_cartao):
chave = os.getenv('ENCRYPTION_KEY') # Armazenar em variável de ambiente
cipher = Fernet(chave)
cartao_criptografado = cipher.encrypt(numero_cartao.encode())
return cartao_criptografado
def descriptografar_cartao(cartao_criptografado):
chave = os.getenv('ENCRYPTION_KEY')
cipher = Fernet(chave)
return cipher.decrypt(cartao_criptografado).decode()</code></pre>
<p>Nunca coloque chaves de criptografia no código. Use variáveis de ambiente, vaults (HashiCorp Vault, AWS Secrets Manager) ou sistemas de gerenciamento de segredos. Em desenvolvimento local, use <code>.env</code> com <code>.gitignore</code>.</p>
<h2>Validação de Entrada e Prevenção de Ataques Comuns</h2>
<p>SQL Injection, XSS e CSRF destroem APIs inseguras. A defesa começa com validação rigorosa de entrada. Não confie em dados que vêm do cliente — valide tipo, tamanho, formato e conteúdo.</p>
<p>Use bibliotecas especializadas para validação. Para SQL Injection, use prepared statements ou ORMs (SQLAlchemy, Django ORM). Para XSS, sanitize saída e use Content Security Policy headers. CSRF é menos preocupante em APIs stateless, mas CORS mal configurado expõe suas APIs.</p>
<pre><code class="language-python"># Exemplo com validação e proteção
from flask import Flask, request
from sqlalchemy import text
from pydantic import BaseModel, EmailStr, validator
import re
app = Flask(__name__)
Validação com Pydantic (recomendado)
class CriarUsuario(BaseModel):
email: EmailStr
nome: str
idade: int
@validator('nome')
def nome_valido(cls, v):
if len(v) < 3 or len(v) > 100:
raise ValueError('Nome deve ter 3-100 caracteres')
if not re.match(r'^[a-zA-Z\s]+$', v):
raise ValueError('Nome apenas com letras')
return v
@validator('idade')
def idade_valida(cls, v):
if v < 18 or v > 120:
raise ValueError('Idade entre 18 e 120')
return v
@app.route('/usuarios', methods=['POST'])
def criar_usuario():
try:
dados = CriarUsuario(**request.get_json())
except ValueError as e:
return {'erro': str(e)}, 400
Usar prepared statement (não concatenar strings!)
query = text("INSERT INTO usuarios (email, nome, idade) VALUES (:email, :nome, :idade)")
db.session.execute(query, {
'email': dados.email,
'nome': dados.nome,
'idade': dados.idade
})
db.session.commit()
return {'id': usuario.id}, 201
Headers de segurança
@app.after_request
def adicionar_headers_seguranca(response):
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-XSS-Protection'] = '1; mode=block'
response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
return response</code></pre>
<p>Configure CORS restritivamente: liste domínios explícitos, não use <code>*</code> em produção. Implemente rate limiting para prevenir brute force e DDoS. Use bibliotecas como <code>Flask-Limiter</code>.</p>
<h2>Logging, Monitoramento e Resposta a Incidentes</h2>
<p>Você não pode proteger o que não monitora. Logar acessos, erros e comportamentos suspeitos é essencial. Mas cuidado: não logue senhas, tokens ou dados sensíveis. Estruture logs em JSON para análise automatizada.</p>
<p>Em produção, centralize logs (ELK Stack, Splunk, CloudWatch). Configure alertas para anomalias: múltiplas falhas de autenticação, alterações em dados críticos, requisições de IPs suspeitos. Ter um plano de resposta a incidentes — quem faz o quê quando a segurança é comprometida — é tão importante quanto evitar o incidente.</p>
<pre><code class="language-python"># Exemplo com logging estruturado
import logging
import json
from datetime import datetime
Configurar logger JSON
class LoggerJSON(logging.Formatter):
def format(self, record):
log_data = {
'timestamp': datetime.utcnow().isoformat(),
'level': record.levelname,
'message': record.getMessage(),
'module': record.module
}
return json.dumps(log_data)
logger = logging.getLogger(__name__)
handler = logging.StreamHandler()
handler.setFormatter(LoggerJSON())
logger.addHandler(handler)
logger.setLevel(logging.INFO)
@app.route('/api/transferencia', methods=['POST'])
@token_obrigatorio
def transferencia():
dados = request.get_json()
logger.info({
'acao': 'transferencia_iniciada',
'usuario_id': request.usuario_id,
'valor': dados['valor'],
'para': dados['para_conta']
})
Processar transferência
logger.info({
'acao': 'transferencia_concluida',
'usuario_id': request.usuario_id
})
return {'sucesso': True}</code></pre>
<p>Implemente versionamento de API para facilitar rollback de vulnerabilidades descobertas. Mantenha dependências atualizadas e faça auditorias de segurança regularmente com ferramentas como <code>bandit</code> (Python) ou <code>npm audit</code> (Node.js).</p>
<h2>Conclusão</h2>
<p>Dominar segurança em APIs é um processo contínuo. Os três pilares que você deve praticar imediatamente são: <strong>(1) Autenticação e autorização robustas com JWT, garantindo que apenas usuários legítimos acessem dados apropriados; (2) Proteção de dados com HTTPS, criptografia em repouso e bcrypt para senhas; (3) Validação rigorosa de entrada e monitoramento constante</strong> para detectar e responder a ataques antes que causem danos. Lembre-se: segurança não é um destino, é uma jornada de melhoria contínua.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://owasp.org/www-project-api-security/" target="_blank" rel="noopener noreferrer">OWASP API Security Top 10</a> — Guia essencial sobre vulnerabilidades em APIs</li>
<li><a href="https://jwt.io/" target="_blank" rel="noopener noreferrer">JWT.io</a> — Documentação oficial e ferramenta interativa para JWT</li>
<li><a href="https://pypi.org/project/bcrypt/" target="_blank" rel="noopener noreferrer">Bcrypt Documentation</a> — Biblioteca para hashing seguro de senhas</li>
<li><a href="https://flask-security-too.readthedocs.io/" target="_blank" rel="noopener noreferrer">Flask Security</a> — Extensão Flask com autenticação e proteção integradas</li>
<li><a href="https://www.nist.gov/cyberframework/" target="_blank" rel="noopener noreferrer">NIST Cybersecurity Framework</a> — Padrão corporativo para segurança da informação</li>
</ul>