Como se tornar um desenvolvedor backend: Fundamentos de Web Security

Como se tornar um desenvolvedor backend: Fundamentos de Web Security

O desenvolvimento backend é uma área da programação que envolve a criação e manutenção da parte lógica e funcional de um site ou aplicativo web, como o banco de dados, a API, o servidor e a integração com outros serviços. Um desenvolvedor backend é responsável por garantir que os dados sejam armazenados, processados e transmitidos de forma segura, eficiente e confiável entre o frontend (a interface gráfica que o usuário vê e interage) e o backend.

Um dos aspectos mais importantes e desafiadores do desenvolvimento backend é a segurança web, ou seja, o conjunto de práticas e técnicas que visam proteger os dados e os recursos de um site ou aplicativo web contra ataques maliciosos, como invasão, roubo, alteração, negação de serviço, entre outros. A segurança web é essencial para garantir a privacidade, a integridade e a disponibilidade dos dados dos usuários e dos clientes, bem como para evitar prejuízos financeiros, legais e de reputação para os desenvolvedores e as empresas.

Neste artigo, vamos abordar alguns dos fundamentos de segurança web que todo desenvolvedor backend deve conhecer e aplicar em seus projetos. Vamos ver quais são as principais ameaças e vulnerabilidades que afetam os sites e aplicativos web, como preveni-las e mitigá-las, e quais são as melhores práticas e ferramentas para implementar uma segurança web eficaz. Também vamos mostrar alguns exemplos de código que ilustram os conceitos discutidos no artigo.


Principais ameaças e vulnerabilidades

As ameaças e vulnerabilidades que afetam os sites e aplicativos web são diversas e variam de acordo com o tipo, a complexidade e a finalidade do projeto. No entanto, existem algumas categorias gerais que podem ser consideradas como as mais comuns e perigosas:

  • Injeção: é um tipo de ataque que consiste em inserir código malicioso ou comandos indesejados em um site ou aplicativo web, por meio de entradas de dados fornecidas pelo usuário ou por outros meios. O objetivo é executar esse código ou comando no contexto do site ou aplicativo web, podendo comprometer o seu funcionamento, acessar ou modificar dados sensíveis, ou realizar outras ações maliciosas. Um exemplo clássico de injeção é o SQL Injection, em que o atacante insere uma consulta SQL maliciosa em um campo de entrada de dados (como um formulário ou uma URL), que é enviada ao banco de dados do site ou aplicativo web, podendo ler, alterar ou apagar dados, ou até mesmo executar comandos arbitrários no servidor. Outros exemplos de injeção são o Command Injection, o Code Injection, o LDAP Injection, o XPath Injection, entre outros.
  • Quebra de autenticação: é um tipo de ataque que visa obter acesso não autorizado a um site ou aplicativo web, por meio da exploração de falhas nos mecanismos de autenticação (o processo que verifica a identidade do usuário) ou de gerenciamento de sessão (o processo que mantém o estado do usuário após a autenticação). O objetivo é assumir a identidade de um usuário legítimo ou obter privilégios elevados no site ou aplicativo web, podendo acessar ou modificar dados restritos, ou realizar outras ações maliciosas. Alguns exemplos de quebra de autenticação são o Brute Force Attack (em que o atacante tenta adivinhar as credenciais do usuário por meio de tentativas repetidas), o Session Hijacking (em que o atacante captura ou manipula o identificador da sessão do usuário), o Session Fixation (em que o atacante força o usuário a usar um identificador da sessão pré-definido pelo atacante), entre outros.
  • Exposição de dados sensíveis: é um tipo de ataque que visa obter acesso não autorizado a dados sensíveis armazenados ou transmitidos por um site ou aplicativo web, por meio da exploração de falhas nos mecanismos de criptografia (o processo que transforma os dados em uma forma ilegível para quem não possui a chave) ou de proteção de dados (o processo que restringe o acesso aos dados de acordo com o nível de autorização). O objetivo é ler, copiar ou divulgar esses dados, podendo causar danos à privacidade, à integridade e à confidencialidade dos usuários e dos clientes, bem como prejuízos financeiros, legais e de reputação para os desenvolvedores e as empresas. Alguns exemplos de exposição de dados sensíveis são o Man-in-the-Middle Attack (em que o atacante intercepta e modifica os dados transmitidos entre o usuário e o site ou aplicativo web), o Data Breach (em que o atacante obtém acesso aos dados armazenados no servidor ou no banco de dados do site ou aplicativo web), o Weak Encryption (em que o atacante consegue quebrar a criptografia usada para proteger os dados), entre outros.
  • Cross-Site Scripting (XSS): é um tipo de ataque que consiste em inserir código malicioso ou comandos indesejados em um site ou aplicativo web, por meio de entradas de dados fornecidas pelo usuário ou por outros meios. O objetivo é executar esse código ou comando no navegador do usuário, podendo comprometer a sua experiência, acessar ou modificar dados sensíveis, ou realizar outras ações maliciosas. Um exemplo típico de XSS é o Reflected XSS, em que o atacante envia uma URL maliciosa ao usuário (por exemplo, por e-mail ou por redes sociais), que contém um código ou comando injetado em um parâmetro da URL. Quando o usuário clica na URL, o código ou comando é refletido pelo site ou aplicativo web e executado no navegador do usuário. Outros exemplos de XSS são o Stored XSS (em que o código ou comando injetado é armazenado no servidor ou no banco de dados do site ou aplicativo web é executado sempre que o usuário acessa uma página específica) e o DOM-based XSS (em que o código ou comando injetado é executado no navegador do usuário por meio da manipulação do Document Object Model (DOM) da página).
  • Cross-Site Request Forgery (CSRF): é um tipo de ataque que consiste em induzir o usuário a realizar uma ação indesejada em um site ou aplicativo web, por meio da exploração da confiança que o site ou aplicativo web tem na sessão do usuário. O objetivo é fazer com que o usuário envie uma requisição HTTP forjada ao site ou aplicativo web, podendo alterar os seus dados, as suas preferências, as suas permissões, ou realizar outras ações maliciosas. Um exemplo comum de CSRF é o seguinte: o usuário está logado em um site de banco online e recebe um e-mail com um link para um site malicioso. Ao clicar no link, o usuário é levado a uma página que contém uma imagem oculta com um atributo src que aponta para uma URL do site de banco online, com um parâmetro que indica uma transferência bancária para a conta do atacante. Como o usuário está logado no site de banco online, a requisição HTTP forjada é enviada com o seu identificador da sessão e a transferência bancária é realizada sem o seu consentimento.

Como prevenir e mitigar as ameaças e vulnerabilidades

Para prevenir e mitigar as ameaças e vulnerabilidades descritas acima, existem algumas medidas gerais e específicas que todo desenvolvedor backend deve adotar em seus projetos em 2023. Vamos ver algumas delas:

  • Validar as entradas de dados: consiste em verificar se os dados fornecidos pelo usuário ou por outros meios são válidos, completos e consistentes com as regras de negócio do site ou aplicativo web. O objetivo é evitar que dados inválidos, incompletos ou inconsistentes sejam enviados ao backend, podendo causar erros, falhas ou vulnerabilidades. A validação das entradas de dados deve ser feita tanto no frontend quanto no backend, usando técnicas como filtros, sanitização, codificação, escape, entre outras. Por exemplo, para evitar injeções SQL, é recomendável usar consultas parametrizadas ao invés de concatenar strings diretamente na consulta SQL. Veja um exemplo em Python:

# Exemplo de consulta SQL vulnerável a injeção
username = input("Enter your username: ")
password = input("Enter your password: ")
query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'"
result = db.execute(query)

Esse código é vulnerável a injeção porque concatena as entradas do usuário diretamente na consulta SQL, sem validar, filtrar ou escapar os caracteres especiais que podem ser usados para alterar a lógica da consulta. Por exemplo, se o usuário digitar ' OR 1 = 1 -- como username e qualquer coisa como password, a consulta SQL resultante será:

SELECT * FROM users WHERE username = '' OR 1 = 1 --' AND password = 'qualquer coisa'


Essa consulta SQL retornará todos os registros da tabela users, pois a condição 1 = 1 é sempre verdadeira e o restante da consulta é ignorado pelo comentário --. Assim, o atacante poderá obter acesso ao site ou aplicativo web sem conhecer as credenciais válidas de nenhum usuário.

Exemplo de consulta SQL protegida contra injeção

username = input("Enter your username: "

password = input("Enter your password: "

query = "SELECT * FROM users WHERE username = ? AND password = ?" result = db.execute(query, (username, password))

  • Fortalecer a autenticação e o gerenciamento de sessão: consiste em implementar mecanismos robustos e seguros para verificar a identidade do usuário e manter o seu estado após a autenticação. O objetivo é evitar que usuários não autorizados ou mal-intencionados obtenham acesso ou privilégios indevidos no site ou aplicativo web. Algumas boas práticas para fortalecer a autenticação e o gerenciamento de sessão são: usar protocolos seguros como HTTPS, SSL/TLS, OAuth, entre outros; usar algoritmos de hash e de sal para armazenar as senhas dos usuários; usar mecanismos de verificação em duas etapas ou multifator; usar identificadores de sessão aleatórios, únicos e de curta duração; invalidar os identificadores de sessão após o logout ou após um período de inatividade; limitar o número de tentativas de login; entre outras. Por exemplo, para gerar um identificador de sessão seguro em Python, é possível usar a biblioteca secrets:

# Exemplo de geração de um identificador de sessão seguro
import secrets
session_id = secrets.token_urlsafe(32)


  • Criptografar e proteger os dados sensíveis: consiste em transformar os dados sensíveis em uma forma ilegível para quem não possui a chave e restringir o acesso aos dados de acordo com o nível de autorização. O objetivo é evitar que os dados sensíveis sejam expostos, copiados ou divulgados por atacantes ou por terceiros não autorizados. Algumas boas práticas para criptografar e proteger os dados sensíveis são: usar algoritmos de criptografia fortes e atualizados, como AES, RSA, SHA, entre outros; usar chaves suficientemente longas e aleatórias; armazenar as chaves em locais seguros e separados dos dados; usar certificados digitais confiáveis; usar protocolos seguros como HTTPS, SSL/TLS, VPN, entre outros; aplicar o princípio do menor privilégio, ou seja, conceder apenas os acessos necessários aos dados para cada usuário ou função; entre outras. Por exemplo, para criptografar um dado sensível em Python, é possível usar a biblioteca cryptography:

# Exemplo de criptografia de um dado sensível
from cryptography.fernet import Fernet
key = Fernet.generate_key() # Gerar uma chave aleatória
f = Fernet(key) # Criar um objeto Fernet com a chave
data = b"Hello World" # Dado sensível a ser criptografado
encrypted_data = f.encrypt(data) # Criptografar o dado com a chave


  • Prevenir XSS: consiste em evitar que código malicioso ou comandos indesejados sejam inseridos e executados no navegador do usuário. O objetivo é evitar que o usuário tenha a sua experiência comprometida, os seus dados acessados ou modificados, ou outras ações maliciosas realizadas por atacantes. Algumas boas práticas para prevenir XSS são: validar as entradas de dados fornecidas pelo usuário ou por outros meios; codificar ou escapar os caracteres especiais que podem ser interpretados como código pelo navegador; usar cabeçalhos HTTP como Content-Type, X-Frame-Options, Content-Security-Policy, entre outros; usar bibliotecas ou frameworks que oferecem proteção contra XSS, como React, Angular, Django, entre outros. Por exemplo, para escapar os caracteres especiais em Python, é possível usar a biblioteca html:

# Exemplo de escape dos caracteres especiais
import html
data = "<script>alert('XSS')</script>" # Dado fornecido pelo usuário que contém código malicioso
escaped_data = html.escape(data) # Escapar os caracteres especiais
print(escaped_data) # &lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;


  • Prevenir CSRF: consiste em evitar que o usuário realize uma ação indesejada em um site ou aplicativo web, por meio da exploração da confiança que o site ou aplicativo web tem na sessão do usuário. O objetivo é evitar que o usuário envie uma requisição HTTP forjada ao site ou aplicativo web, alterando os seus dados, as suas preferências, as suas permissões, ou realizando outras ações maliciosas. Algumas boas práticas para prevenir CSRF são: usar tokens CSRF, ou seja, valores aleatórios e únicos que são gerados pelo site ou aplicativo web e enviados ao usuário junto com o formulário ou a requisição HTTP, e que devem ser devolvidos pelo usuário na resposta, para verificar a origem e a autenticidade da requisição; usar cabeçalhos HTTP como Origin, Referer, X-Requested-With, entre outros; usar mecanismos de verificação em duas etapas ou multifator; entre outras. Por exemplo, para usar tokens CSRF em Python, é possível usar a biblioteca Flask-WTF:

# Exemplo de uso de tokens CSRF
from flask import Flask, render_template
from flask_wtf import FlaskForm
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)
app.config["SECRET_KEY"] = "secret" # Definir uma chave secreta para gerar os tokens CSRF
csrf = CSRFProtect(app) # Criar um objeto CSRFProtect com a aplicação

class TransferForm(FlaskForm): # Criar um formulário de transferência bancária
    amount = IntegerField("Amount") # Campo para o valor da transferência
    account = StringField("Account") # Campo para a conta de destino
    submit = SubmitField("Transfer") # Botão para enviar o formulário

@app.route("/", methods=["GET", "POST"])
def index():
    form = TransferForm() # Criar uma instância do formulário
    if form.validate_on_submit(): # Se o formulário for válido (incluindo o token CSRF)
        amount = form.amount.data # Obter o valor da transferência
        account = form.account.data # Obter a conta de destino
        # Realizar a transferência bancária ...
        return "Transfer successful" # Retornar uma mensagem de sucesso
    return render_template("index.html", form=form) # Renderizar o template do formulário

Conclusão

Neste artigo, vimos alguns dos fundamentos de segurança web que todo desenvolvedor backend deve conhecer e aplicar em seus projetos. Vimos quais são as principais ameaças e vulnerabilidades que afetam os sites e aplicativos web, como preveni-las e mitigá-las, e quais são as melhores práticas e ferramentas para implementar uma segurança web eficaz. Também mostramos alguns exemplos de código que ilustram os conceitos discutidos no artigo.

A segurança web é um tema amplo e complexo, que requer constante atualização e aprendizado. Não existe uma solução única ou definitiva para garantir a segurança web de um site ou aplicativo web, mas sim um conjunto de medidas complementares e adaptáveis às necessidades e aos riscos de cada projeto. Por isso, é importante que os desenvolvedores backend estejam sempre atentos às novidades e às tendências da área, bem como às recomendações e aos padrões estabelecidos por organizações e comunidades especializadas.

Esperamos que este artigo tenha sido útil e informativo para você. Se você gostou deste artigo, compartilhe com os seus amigos e colegas.

Obrigado pela sua leitura!

Referências Bibliográficas

  • OWASP. OWASP Top 10 - 2021. Disponível em: https://owasp.org/Top10/
  • MDN Web Docs. Web security. Disponível em: https://developer.mozilla.org/en-US/docs/Web/Security
  • W3Schools. Web Security Tutorial. Disponível em: https://www.w3schools.com/websecurity/default.asp
  • Python Software Foundation. Python Documentation. Disponível em: https://docs.python.org/3/
  • Pallets Projects. Flask Documentation. Disponível em: https://flask.palletsprojects.com/en/2.0.x/
💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.