Skip to main content

Como encontrar e corrigir referências diretas inseguras a objetos em Python

Escrito por

Keshav Malik

feature python linting

19 de julho de 2023

0 minutos de leitura

Uma referência direta insegura a objetos (IDOR) é uma vulnerabilidade de segurança que ocorre quando a implementação de um sistema permite que invasores acessem e manipulem diretamente objetos ou recursos confidenciais sem verificações de autorização. Por exemplo, uma IDOR pode surgir quando um aplicativo dá acesso direto a objetos com base em dados fornecidos pelo usuário, permitindo que um invasor contorne a autorização.

Entenda as vulnerabilidades IDOR

Precisamos combater as IDORs para manter a confidencialidade, a integridade e a disponibilidade dos dados confidenciais tratados pelos seus aplicativos Python. Os desenvolvedores precisam entender as vulnerabilidades IDOR para evitar acessos não autorizados, preservar a confiança dos usuários e evitar consequências financeiras e legais potencialmente graves.

Tipos de IDOR

As IDORs podem assumir diferentes formas, dependendo da implementação e das funcionalidades do aplicativo.

IDOR com referência a objetos

Esse tipo de IDOR ocorre quando um invasor consegue acessar ou modificar um objeto sem autorização. Um exemplo comum é quando um aplicativo web permite o acesso a dados confidenciais, como contas bancárias, por meio de uma solicitação simples, como example.com/accounts?id={account_id}. Se o aplicativo não verificar corretamente as permissões de quem faz a solicitação, usuários não autorizados poderão visualizar ou manipular informações da conta.

IDOR com referência a arquivos

Esse tipo de IDOR envolve a recuperação não autorizada de arquivos. Por exemplo, se um aplicativo de chat armazena registros confidenciais de conversas em arquivos numerados em sequência, um invasor pode acessar conversas privadas fazendo solicitações com números semelhantes — example.com/1.log, example.com/2.log e assim por diante.

IDOR cega

Uma IDOR cega ocorre quando a exploração não fica diretamente visível na resposta do servidor, embora possa ter havido uma modificação não autorizada. Com uma IDOR cega, um invasor consegue alterar os dados privados de outro usuário sem visualizá-los. Por exemplo, se um aplicativo web permite que um usuário modifique as configurações do perfil por meio de uma chamada de API, como example.com/users/update?id={user_id}, um invasor pode alterar o user_id na solicitação e modificar as configurações do perfil de alguém sem visualizar diretamente seus dados.

Padrões comuns para identificar vulnerabilidades IDOR no código

Para detectar vulnerabilidades IDOR no código, é preciso estar atento e conhecer os padrões comuns:

  • Falta de controle de acesso: um aplicativo que usa dados fornecidos pelo usuário para acessar recursos diretamente, sem verificar a autorização desse usuário, provavelmente tem uma vulnerabilidade IDOR.

  • Identificadores fáceis de adivinhar: identificadores fáceis de adivinhar — como números inteiros sequenciais (user_id=99001) ou strings curtas (user_id=user1) — aumentam o risco de vulnerabilidades IDOR em um aplicativo. Usar identificadores difíceis de adivinhar, como identificadores universais exclusivos (UUIDs), pode reduzir esse risco.

  • Acesso direto a arquivos: um aplicativo que dá aos usuários acesso direto a recursos, como imagens ou arquivos CSV, por meio de URLs ou parâmetros de solicitação está vulnerável a IDORs. Precisamos garantir a existência de mecanismos de controle adequados para impedir que os usuários acessem arquivos diretamente.

Criando um aplicativo Python vulnerável a IDOR com FastAPI

Nesta seção, vamos criar uma API web vulnerável a IDOR usando o framework Python FastAPI. Depois, veremos como corrigir a vulnerabilidade.

Para acompanhar este tutorial prático, verifique se o Python 3.x está instalado na sua máquina.

Primeiros passos

Primeiro, precisamos criar um aplicativo. Crie um novo diretório para o projeto e acesse-o:

mkdir fastapi-app; cd fastapi-app

Em seguida, instale FastAPI, Uvicorn, SQLAlchemy e SQLite com o seguinte comando:

pip install fastapi uvicorn sqlalchemy

Por fim, crie um arquivo chamado main.py no diretório do projeto.

Criando uma API vulnerável com FastAPI

Agora que configuramos a estrutura de diretórios e os requisitos, vamos escrever o código com uma vulnerabilidade IDOR. Primeiro, copie o código abaixo para main.py:

from fastapi import FastAPI, HTTPException, Depends
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session

app = FastAPI()

# SQLite database configuration
DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

# User model
class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    uuid = Column(String, unique=True, index=True)
    username = Column(String, unique=True, index=True)
    email = Column(String, unique=True, index=True)

Base.metadata.create_all(bind=engine)

# Dependency for database session
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/users/{user_id}")
async def get_user_by_id(user_id: int, db: Session = Depends(get_db)):
    user = db.query(User).filter(User.id == user_id).first()
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return user

A vulnerabilidade IDOR está no endpoint /users/user_id. Como o aplicativo não tem controles de acesso, qualquer usuário pode visualizar os dados de outros usuários alterando o user_id na URL.

Como identificar e corrigir vulnerabilidades IDOR

Agora, vamos encontrar e corrigir a falha de segurança IDOR no nosso aplicativo FastAPI.

Como encontrar vulnerabilidades

Para identificar vulnerabilidades IDOR, precisamos procurar padrões específicos no código. No aplicativo FastAPI, devemos analisar o endpoint /users/{user_id}, que representa uma possível vulnerabilidade IDOR pelos seguintes motivos:

  • Referências diretas a objetos sem proteção: na função get_user_by_id, o parâmetro user_id faz referência direta ao objeto User no banco de dados. Como não há mecanismos de controle de acesso para proteger essa referência, qualquer cliente pode alterar o valor de user_id na solicitação e acessar os dados de outros usuários.

  • Falta de autorização: na mesma função get_user_by_id, não há verificações para confirmar se o usuário que fez a solicitação tem autorização para acessar os dados solicitados. Qualquer usuário pode acessar os dados de outra pessoa alterando o parâmetro user_id.

Corrigindo o código vulnerável

Para corrigir a vulnerabilidade IDOR, precisamos atualizar o endpoint /users/{user_id} e incluir verificações adequadas de controle de acesso.

Vamos simular um usuário autenticado e permitir o acesso somente se o user_id na URL corresponder ao ID do usuário autenticado. Para fins de demonstração, vamos supor que o ID do usuário autenticado seja 1. Veja o código atualizado:

@app.get("/users/{user_id}")
async def get_secure_user(user_id: int, db: Session = Depends(get_db)):
    # Assume user authentication and authorization are performed here
    authenticated_user_id = "hbecec-edeek-wxwexe-cdcece" # better to use UUIDs

    if authenticated_user_id != user_id:
        raise HTTPException(status_code=403, detail="Not authorized to access this user")

    user = db.query(User).filter(User.id == user_id).first()
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return user

Neste trecho de código, adicionamos uma verificação de controle de acesso que compara o user_id da URL com o authenticated_user_id. Se os IDs forem diferentes, o aplicativo retorna um erro HTTP 403 Forbidden. Esse erro impede que usuários não autorizados acessem informações de outras pessoas, corrigindo a vulnerabilidade IDOR.

Detecte e corrija problemas de segurança com a Snyk

A Snyk é uma solução de segurança com recursos de análise de composição de software (SCA) e teste de segurança estática de aplicativos (SAST). Vamos usar a Snyk para encontrar e corrigir problemas de segurança no nosso aplicativo FastAPI.

Instale e autentique a Snyk CLI

Para começar, instale a Snyk CLI na sua máquina seguindo as instruções de instalação na documentação.

Depois de instalar a CLI, autentique sua conta da Snyk. Execute o comando snyk auth no terminal. Uma janela do navegador será aberta para você entrar com sua conta do GitHub ou do Google.

Verifique se há vulnerabilidades nas dependências

Para verificar se há vulnerabilidades nas bibliotecas de terceiros do projeto, precisamos de um arquivo requirements.txt. Crie o arquivo requirements.txt com o seguinte comando:

pip freeze > requirements.txt

Em seguida, verifique se há vulnerabilidades nas dependências do projeto executando o seguinte comando no terminal:

snyk test --file=requirements.txt --skip-unresolved

Esse comando analisa suas dependências, identifica e descreve vulnerabilidades, informa a gravidade de cada uma e oferece orientações para corrigi-las. Por exemplo, você pode encontrar uma vulnerabilidade de negação de serviço (DoS) de gravidade média em starlette@0.14.2.

Observação: a Snyk não consegue verificar o projeto se estiver faltando um pacote necessário. A flag –skip-unresolved ignora esse comportamento.

Corrija vulnerabilidades com a Snyk

A Snyk também pode ajudar a corrigir vulnerabilidades. O comando snyk fix pode resolver automaticamente alguns dos problemas identificados. A Snyk atualiza ou aplica patches às dependências afetadas para deixá-las em versões seguras, mantendo os aplicativos atualizados e protegidos.

Use Snyk Code para análise estática de código

A Snyk também oferece uma poderosa solução de teste de segurança estática de aplicativos (SAST). O comando snyk code analisa o código do seu aplicativo, identifica problemas de segurança e fornece informações detalhadas sobre como corrigi-los.

Para usar snyk code, execute o seguinte comando no terminal:

snyk code test

A Snyk Code faz uma análise aprofundada da sua base de código e destaca as vulnerabilidades de segurança encontradas. Ela também oferece orientações para corrigir esses problemas, ajudando você a manter um aplicativo seguro e confiável.

Entenda as vulnerabilidades IDOR

Como desenvolvedores, precisamos garantir a segurança dos nossos aplicativos. As IDORs representam uma ameaça aos aplicativos web, por isso precisamos aprender a identificá-las e corrigi-las. Com um bom conhecimento das vulnerabilidades IDOR, você pode criar aplicativos Python eficientes e seguros.

Neste tutorial, você aprendeu a encontrar e corrigir vulnerabilidades IDOR em um aplicativo Python. Também vimos como a Snyk pode ajudar a identificar e corrigir riscos de segurança nas dependências do seu projeto e no próprio código do aplicativo. A Snyk é uma poderosa ferramenta de segurança. Integrá-la à sua rotina de desenvolvimento adiciona uma camada extra de proteção para manter seu código seguro.

Conheça melhor os recursos da Snyk com uma avaliação gratuita.

Comece a participar de desafios de Capture the Flag

Aprenda a resolver desafios de Capture the Flag assistindo sob demanda ao nosso workshop virtual introdutório.