UC02836 · Segurança no desenvolvimento
Aulify · Componente Tecnológica

Segurança no desenvolvimento de software

OWASP Top 10, validação, autenticação, secrets
UC02836 · 25 horas · 2,25 pontos Nível 4 · TDS · Ano 2
Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

Resultados de aprendizagem

  1. Reconhecer vulnerabilidades comuns (OWASP Top 10).
  2. Aplicar validação e sanitização de input.
  3. Implementar autenticação e gestão de sessão seguras.
  4. Proteger secrets e credenciais.
Software inseguro é a porta mais aberta para ataques. Não basta funcionar — tem de resistir a quem quer destruí-lo.
Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento
Bloco 1 · OWASP Top 10

Os 10 inimigos mais perigosos

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

OWASP Top 10 (2021/2023)

  1. Broken Access Control
  2. Cryptographic Failures
  3. Injection (SQL, NoSQL, OS, LDAP)
  4. Insecure Design
  5. Security Misconfiguration
  6. Vulnerable and Outdated Components
  7. Identification and Authentication Failures
  8. Software and Data Integrity Failures
  9. Security Logging and Monitoring Failures
  10. Server-Side Request Forgery (SSRF)
Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

Injection · SQL injection

# ERRADO
nome = request.form["nome"]
query = f"SELECT * FROM users WHERE nome = '{nome}'"
cursor.execute(query)

# Input malicioso: nome = "Ana' OR '1'='1"
# Resulta em: SELECT * FROM users WHERE nome = 'Ana' OR '1'='1'
# Devolve TODOS os utilizadores
# CORRECTO — prepared statement
cursor.execute("SELECT * FROM users WHERE nome = %s", (nome,))

Driver da BD escapa automaticamente. Nunca concatenar.

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

XSS · Cross-Site Scripting

<!-- ERRADO: insere HTML do utilizador sem escapar -->
<p>Olá, {{ nome }}!</p>

<!-- Input malicioso: nome = <script>alert('XSS')</script> -->

Frameworks modernos (Jinja2, React, Vue) escapam por defeito. Cuidado com |safe, dangerouslySetInnerHTML, v-html.

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento
Bloco 2 · Autenticação

Sessões e palavras-passe

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

Armazenar palavras-passe

NUNCA em texto plano. NUNCA em MD5/SHA1.

# CORRECTO — bcrypt
import bcrypt

# Hashing
pwd = "senha-do-utilizador"
hashed = bcrypt.hashpw(pwd.encode(), bcrypt.gensalt(rounds=12))

# Verificar
if bcrypt.checkpw(pwd.encode(), hashed):
    print("Login OK")

bcrypt, scrypt e argon2 são adequadas. Salt automático, lento intencionalmente (resistente a brute-force).

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

MFA · multi-factor authentication

Algo que sabes (senha) + algo que tens (telefone, chave) + algo que és (biometria).

  • TOTP (Google Authenticator, Authy) — codigo de 6 dígitos rotativo.
  • WebAuthn / FIDO2 — chave física (YubiKey) ou Touch ID.
  • SMS — menos seguro (SIM swap), mas melhor que nada.

Em 2026, MFA é obrigatório em qualquer serviço que mexa com dados.

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

Sessões seguras

# Flask
app.config.update(
    SESSION_COOKIE_HTTPONLY=True,   # JS não acede
    SESSION_COOKIE_SECURE=True,     # só HTTPS
    SESSION_COOKIE_SAMESITE="Lax",  # protege CSRF
    PERMANENT_SESSION_LIFETIME=timedelta(hours=2),
)

Ou usar JWT com expiração curta + refresh token. Cuidados: token comprometido = acesso até expirar.

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento
Bloco 3 · Validação

Nunca confiar no cliente

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

Validação no servidor

Validação no cliente (browser) é só UX — pode ser ignorada com curl/Postman.

# Pydantic (FastAPI)
from pydantic import BaseModel, EmailStr, Field

class RegistarUtilizador(BaseModel):
    email: EmailStr
    nome: str = Field(min_length=2, max_length=100)
    idade: int = Field(ge=13, le=120)
    password: str = Field(min_length=10)

Servidor rejeita input inválido com 400 Bad Request.

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

Sanitização

Diferente de validação. Sanitização limpa input mantendo-o funcional.

import bleach

# Remove tags HTML excepto whitelist segura
html_seguro = bleach.clean(
    user_html,
    tags=["p", "b", "i", "a"],
    attributes={"a": ["href"]}
)

Use bleach (Python), DOMPurify (JS) para conteúdo gerado por utilizador.

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento
Bloco 4 · Secrets

Não comites palavras-passe

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

.env e gitignore

# .gitignore
.env
secrets.json
*.pem
*.key
config.local.py
# .env (NÃO comita)
DATABASE_URL=postgres://user:pass@host/db
SECRET_KEY=k9sj3...
SMTP_PASSWORD=...

# main.py
import os
from dotenv import load_dotenv

load_dotenv()
db_url = os.environ["DATABASE_URL"]
Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

Secrets em produção

  • Variáveis de ambiente (12-factor app).
  • Cofres de secrets: Vault (Hashicorp), AWS Secrets Manager, Azure Key Vault.
  • Rotação periódica — senhas mudadas a cada 90 dias.
  • Mínimo privilégio — cada serviço só com permissões que precisa.

Se um secret é commitado por engano:

  1. Revogá-lo imediatamente (não basta apagar do Git).
  2. Histórico Git mantém — usar git filter-repo para limpar.
  3. Mudar todas as credenciais possivelmente comprometidas.
Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento
Bloco 5 · Dependências

Não és tu, são as bibliotecas

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

Vulnerable dependencies

70% do código moderno é de terceiros. Vulnerabilidade na lib = vulnerabilidade na app.

Ferramentas:

  • pip-audit (Python) — lista CVEs em pacotes.
  • npm audit (Node).
  • Dependabot (GitHub) — alerta e cria PRs.
  • Snyk, Renovate — alternativas.

Boa prática: review semanal de alertas, actualizar prontamente.

Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento

Supply chain attacks

Atacante consegue publicar package legítimo malicioso (typosquatting) ou comprometer mantenedor genuíno.

Mitigação:

  • Pin de versões em requirements.txt (==1.2.3).
  • Lock files (poetry.lock, package-lock.json).
  • SBOM (Software Bill of Materials).
  • Cuidado com pip install pkg sem verificar.
Aulify · Componente Tecnológica · Cursos Profissionais
UC02836 · Segurança no desenvolvimento
Aulify · UC02836 · Fim

Constrói como se o teu código fosse a primeira porta do banco.

📧 geral@aulify.pt
Aulify · Componente Tecnológica · Cursos Profissionais