Aikido

As 10 principais vulnerabilidades de segurança do Python que os programadores devem evitar

Ruben CamerlynckRuben Camerlynck
|
#
#

Principais vulnerabilidades de segurança do Python

Nos pipelines de desenvolvimento acelerados de hoje, o código Python inseguro pode trazer riscos sérios. O Python é amado pela sua simplicidade, mas essa mesma flexibilidade pode se tornar perigosa se as práticas de codificação segura forem negligenciadas. De armadilhas de injeção de código a bibliotecas de terceiros vulneráveis, mesmo um pequeno descuido pode abrir a porta para invasores. Estudos recentes mostram que milhões de credenciais e chaves API vazaram acidentalmente no código — um lembrete claro de que a segurança não pode ser uma preocupação secundária. Neste artigo, analisaremos algumas das principais vulnerabilidades de segurança no nível da linguagem Python (além das questões relacionadas à estrutura da web), ilustraremos o seu impacto com exemplos reais (incluindo CVEs em bibliotecas populares) e ofereceremos dicas para mitigar cada risco. Também destacaremos como a integração de ferramentas de segurança (como SAST, varredura secreta e verificações de dependência Aikido) no início do seu fluxo de trabalho pode ajudar a detectar esses problemas antes que causem estragos.

As 10 principais vulnerabilidades de segurança do Python

Abaixo estão dez das vulnerabilidades de segurança mais comuns e perigosas em aplicações Python. Para cada uma delas, explicamos como a vulnerabilidade surge, o impacto potencial e como corrigi-la ou evitá-la – com destaque especial para como as ferramentas de segurança modernas podem ajudar.

1. Execução arbitrária de código através de eval() e exec()

Python eval() (e o seu primo exec()) permite a execução dinâmica de código Python a partir de strings. Usado de forma imprudente, eval pode transformar um script simples numa bomba-relógio. Se um invasor conseguir influenciar a string passada para eval(), eles podem executar qualquer código que desejarem – desde imprimir dados até apagar ficheiros ou pior. Como disse um programador, “O problema com eval é que corre o risco de permitir que invasores criem entradas maliciosas... que induzem o seu programa a executar códigos prejudiciais.. Em outras palavras, um eval(entrada_do_utilizador) A chamada pode funcionar hoje com entradas seguras, mas amanhã uma entrada habilmente elaborada (como __import__('os').system('rm -rf /')) poderia limpar o servidor.

Impacto: A execução arbitrária de código é tão grave quanto parece – significa um comprometimento total da aplicação. Os invasores podem roubar dados, modificá-los ou assumir o controlo do host. Este não é um caso teórico: violações reais ocorreram devido ao uso inseguro de evalMesmo que a sua utilização de eval é "seguro" hoje (por exemplo, apenas avaliando expressões matemáticas), cria um vulnerabilidade latente que mudanças futuras podem acidentalmente desencadear.

Mitigação: Nunca utilize eval ou exec em entradas não confiáveis. Na verdade, evite-os completamente, a menos que seja absolutamente necessário. O Python oferece alternativas mais seguras para a maioria dos casos de uso (por exemplo, use a avaliação literal via ast.literal_eval para ler estruturas de dados ou tabelas de despacho para chamar funções, em vez de construir uma string para eval). Sempre valide ou higienize rigorosamente as entradas se for necessária uma execução dinâmica.

Chamada Aikido : Uma boa ferramenta de análise estática (SAST) pode detectar o uso de funções perigosas. A verificação de código Aikido, por exemplo, pode sinalizar instâncias de eval() ou exec() no seu código. Isso ajuda a identificar caminhos de código arriscados durante a revisão de código ou CI – antes cheguem à produção. Ao integrar essa digitalização no seu pipeline, será alertado sempre que um novo uso de eval entra sorrateiramente, para que possa ser refatorado ou examinado imediatamente.

2. Injeção de comando do sistema operativo através de subprocesso ou sistema operacional

Com base no tema da injeção de código, outra armadilha crítica é Injeção de comando do sistema operativo. Isso acontece quando um programa Python passa a entrada do utilizador para comandos do shell do sistema sem a devida sanitização. Funções como os.system(), subprocess.run() (com shell=True), ou mesmo o uso de backticks/popen pode executar comandos shell. Se os dados controlados pelo utilizador forem concatenados nesses comandos, um invasor pode injetar comandos maliciosos. Por exemplo:

# Vulnerable snippet:filename = input("Enter the filename to delete: ")os.system(f"rm -f {filename}")

Um invasor poderia inserir ficheiro.txt; desligar -h agora e, de repente, o nosso inocente script é executado rm -f ficheiro.txt; shutdown -h now. Em um incidente real, os invasores exploraram uma vulnerabilidade do MLflow que se originou da passagem de dados não sanitizados para um sistema operacional chamada dentro de uma função de previsão. Como observam os investigadores de segurança Snyk, a injeção de comandos permite a execução não autorizada de comandos, levando a violações de dados, comprometimento do sistema e outras atividades maliciosas.

Impacto: a injeção de comandos do sistema operativo pode ser devastadora. Os invasores podem encadear comandos para roubar ficheiros confidenciais (por exemplo, ler a configuração ou credenciais da aplicação), criar contas de utilizador backdoor ou penetrar mais profundamente na rede. Como esses comandos são executados com os mesmos privilégios do seu processo Python, o impacto pode variar desde o despejo de um banco de dados até a tomada total do servidor. As violações possibilitadas por injeções de comandos geralmente resultam em graves prejuízos financeiros e danos à reputação.

Mitigação: Nunca concatene diretamente entradas do utilizador em comandos do shell. Se precisar chamar programas externos, use as APIs mais seguras: Python’s subprocesso permite passar argumentos como uma lista (o que evita invocar um shell real). Por exemplo, use subprocess.run(["rm", "-f", nome do ficheiro]) em vez de os.system("rm -f " + nome do ficheiro). Se estiver a utilizar subprocesso com shell=True é inevitável, garantir que as entradas sejam rigorosamente validadas ou higienizadas (por exemplo, permitir apenas nomes de ficheiros alfanuméricos esperados). Além disso, considere usar bibliotecas de alto nível para tarefas do sistema operativo (por exemplo, use o manuseamento de ficheiros do Python em vez de rm para eliminar um ficheiro).

Chamada Aikido : análise estática de código Aikido análise estática de código regras para detectar padrões de injeção de comando. Ele irá avisá-lo se encontrar algo como os.system(entrada_do_utilizador) ou subprocess.Popen(..., shell=True) com entrada variável. Na prática, isso significa que o seu pipeline de CI pode falhar numa compilação se for introduzida uma utilização perigosa. Ao detectar essas falhas durante o desenvolvimento, evita aquele momento «ops» em que um trecho de depuração esquecido ou uma chamada de shell rápida e malfeita se tornam uma porta aberta para os invasores.

3. Secrets codificados Secrets código

Codificar secrets como chaves API, credenciais, tokens ou chaves privadas – no código-fonte é uma prática comum e perigosa. É fácil de fazer (“basta colocar a chave AWS aqui por enquanto…”), mas difícil de desfazer, uma vez que secrets permanecer no histórico de commits mesmo após a remoção. secrets expostos secrets uma mina de ouro para os invasores. Na verdade, os vazamentos de segredos explodiram recentemente: em 2022, uma análise de repositórios públicos do GitHub encontrou 10 milhões secrets expostos em apenas 1 ano (um aumento de 67% em relação ao ano anterior). Isso não é cometido apenas por programadores juniores – acontece em todos os níveis. Uma vez vazados, secrets sido usados em violações graves (por exemplo, um invasor usou credenciais de administrador codificadas no código para violar os sistemas internos da Uber).

Impacto: se um invasor encontrar um segredo (em um repositório público, um backup vazado, uma imagem Docker etc.), ele poderá frequentemente acessar diretamente os seus sistemas. Imagine uma palavra-passe de base de dados codificada – se vazada, um invasor poderia entrar na sua base de dados e extrair dados de utilizadores. Chaves API de nuvem codificadas são ainda piores: os fornecedores de nuvem relatam que credenciais expostas são normalmente exploradas poucos minutos após serem descobertas por bots que vasculham repositórios. O raio de impacto pode incluir comprometimento total do ambiente de nuvem, contas de nuvem elevadas para mineradores de criptomoedas ou acesso não autorizado a serviços confidenciais. Secrets são Secrets «as chaves do reino», portanto, vazá-los é como deixar a porta da frente destrancada para ladrões.

Mitigação: Nunca coloque secrets reais secrets código. Use ficheiros de configuração, variáveis de ambiente ou serviços de gestão de segredos (como HashiCorp Vault, AWS Secrets , etc.) para inserir secrets tempo de execução. Se tiver de incluir uma credencial padrão ou de exemplo no código, certifique-se de que seja um espaço reservado que não seja de produção. Realize varreduras regulares de segredos na sua base de código e histórico; se um segredo escapar, alterne-o imediatamente (ou seja, invalide-o e substitua-o) e elimine o commit, se possível. Empregue o princípio do privilégio mínimo – mesmo que um segredo vaze, um token somente leitura é menos prejudicial do que uma chave administrativa completa.

AlertaAikido : é aqui que as ferramentas de deteção de segredos se destacam. A verificação de segredos Aikido(inspirada em ferramentas como GitGuardian outras) procura automaticamente padrões como chaves API, credenciais, certificados e muito mais nos seus repositórios. Ela pode alertá-lo no momento em que um programador acidentalmente comete um segredo. Integrar essa ferramenta ao seu CI/CD (ou mesmo aos ganchos pré-confirmação) significa que uma chave AWS codificada será sinalizada antes mesmo de chegar ao GitHub. A plataforma Aikidooferece até mesmo remediação automatizada por exemplo, revogando a credencial exposta e orientando o programador a usar um método de armazenamento seguro.

4. Deserialização insegura (abuso de Pickle)

O módulo pickle do Python fornece uma maneira de serializar e desserializar objetos complexos. No entanto, o pickle é notoriamente inseguro por design. Descompactar dados de uma fonte não confiável pode executar código arbitrário durante o processo de desserialização. A própria documentação do Python é muito clara sobre isso: “O módulo pickle não se destina a ser seguro contra dados maliciosos. Nunca deserialize dados recebidos de uma fonte não confiável ou não autenticada. Na prática, isso significa que, se um invasor conseguir alimentar a sua aplicação com um pickle (por exemplo, um cookie falsificado ou um objeto em cache), ele poderá executar qualquer código Python no seu servidor – essencialmente uma vulnerabilidade de RCE (Execução Remota de Código) pré-autenticação.

Exemplo real: Um programador pode usar pickle.loads() em dados recebidos através de uma rede (talvez pensando que é apenas uma forma conveniente de transmitir objetos Python). Os invasores podem criar uma carga pickle que, quando descompactada, executa comandos do sistema. Pesquisadores de segurança demonstraram exploits triviais em que a descompactação de um objeto aparentemente inofensivo aciona um shell reverso para o invasor. Em um caso, um exploit de 15 linhas usando pickle foi suficiente para gerar um shell, porque o aplicativo confiava cegamente nos dados pickle pela rede.

Impacto: A deserialização insegura é uma questão crítica, que normalmente leva à execução completa de código remoto. Como o pickle pode invocar qualquer classe e método durante o carregamento, um invasor pode abusar dele para fazer coisas como excluir ficheiros, instalar malware ou pivotar para outros serviços internos. Ao contrário de algumas vulnerabilidades que "apenas" vazam dados, isso dá controle direto ao invasor. O impacto é limitado apenas pelas permissões da aplicação em execução (e muitas vezes as aplicações Python são executadas com muitos privilégios).

Mitigação: Não utilize pickle (ou serialização semelhante, como marshal) em dados provenientes de fontes não confiáveis. Se precisar trocar dados entre sistemas, use formatos seguros como JSON ou XML – e mesmo assim, seja cauteloso (valide as entradas). Para casos de uso específicos do Python (partilha de objetos), considere jsonpickle em modo seguro ou outros serializadores mais seguros, mas sempre presuma que a entrada pode ser hostil. Se for absolutamente necessário aceitar dados em pickle (por exemplo, por compatibilidade), trate-os como código: exija autenticação, use assinaturas digitais para garantir que sejam de uma fonte confiável ou execute a desserialização em uma sandbox com privilégios restritos. O conselho mais simples geralmente é o melhor: evitar completamente a deserialização dinâmica das entradas do utilizador.

Chamada Aikido : Os modernos scanners de código podem detetar o uso de APIs perigosas, como pickle.loads ou pickle.load em dados potencialmente externos. SAST Aikido, por exemplo, verifica se há deserialização insegura – ele sabe que qualquer invocação do pickle é um sinal de alerta, a menos que se prove o contrário. Ele irá destacar esses casos durante as revisões de código. Além disso, o scanner de dependências Aikidomantém um registo dos CVEs de deserialização conhecidos. Por exemplo, algumas bibliotecas (ou frameworks) tiveram falhas de deserialização (não apenas pickle — até mesmo coisas como XML ou YAML, que abordaremos a seguir). Aikido alertá-lo se estiver a usar uma versão vulnerável de tal biblioteca e sugerir atualizações ou patches.

5. Carregamento inseguro de YAML (vulnerabilidade PyYAML)

Os problemas de serialização não se limitam ao pickle. YAML, um formato de dados amigável para humanos, também pode prejudicá-lo se usado de forma insegura. A popular biblioteca PyYAML tinha uma falha bem conhecida: usar yaml.load() em entradas não confiáveis poderia executar objetos Python arbitrários. Na verdade, o PyYAML carregar() era basicamente tão poderoso quanto o pickle. CVE-2017-18342 foi atribuída a esta questão – «No PyYAML anterior à versão 5.1, a API yaml.load() podia executar código arbitrário se fosse utilizada com dados não confiáveis.» A correção consistiu em introduzir um carregamento_seguro função e marca carregar() padrão para o modo seguro nas versões mais recentes. Mas muitos aplicativos ainda podem usar inadvertidamente o antigo yaml.load (ou uma versão mais antiga do PyYAML), pensando que estão apenas a analisar uma configuração, quando, na realidade, um invasor poderia criar um YAML que executa código.

Impacto: semelhante ao pickle, o impacto é a execução remota de código. Por exemplo, um ficheiro YAML pode incorporar um objeto Python de um tipo que, após a construção, executa uma chamada do sistema. Os invasores que exploram isso podem fazer com que a sua aplicação execute comandos do sistema no momento em que tenta analisar um YAML malicioso. Isso pode ser explorado por meio de qualquer funcionalidade que analise YAML fornecido pelo utilizador (cenários comuns incluem importadores de configuração, modelos Kubernetes em CI/CD ou aplicações web que aceitam entrada YAML). O CVE acima foi marcado como Crítico (CVSS 9.8) precisamente devido à facilidade com que pode ser acionado e à gravidade do resultado.

Mitigação: Use sempre carregamento seguro métodos para formatos de dados. No PyYAML, use yaml.safe_load() for any content that is not fully trusted. This mode only parses basic YAML types (strings, ints, lists, dicts) and will refuse to instantiate custom objects. If you are on PyYAML < 5.1, upgrade the library – the old carregar() é totalmente inseguro. Da mesma forma, tenha cuidado com outros formatos de serialização: use json.carregar (O JSON não tem execução de código por padrão, o que é bom), ou se estiver a usar semelhante a picles alternativas, certifique-se de que elas tenham um modo seguro. Uma ideia de defesa em profundidade: execute a análise num ambiente com privilégios reduzidos ou numa sandbox, se possível (assim, mesmo que o código seja executado, ele não poderá causar muitos danos).

Chamada Aikido : análise de dependências is key here. Aikido’s dependency analyzer would flag that you have PyYAML <5.1 in your requirements, warning you of CVE-2017-18342 and advising an upgrade. On the code side, Aikido’s SAST can also catch usage of yaml.load(...) e sugerimos usar safe_load em vez disso. Trata-se de detectar o problema em dois níveis: certifique-se de que está a usar uma versão segura da biblioteca e de que está a chamar as funções seguras. Ao integrar essas verificações, você será notificado durante o desenvolvimento de que «ei, essa chamada de análise YAML não é segura», com orientações para corrigi-la.

6. Traversal de diretório através de operações de ficheiros inseguras (extração de ficheiros tar)

O manuseio de ficheiros é comum em Python (por exemplo, descompactar arquivos enviados pelos utilizadores). Mas operações ingênuas com ficheiros podem introduzir vulnerabilidades de traversal de caminho. Um exemplo proeminente é o Python integrado arquivo tar módulo. Foi revelado que, durante mais de 15 anos, tarfile.extractall() estava vulnerável a um ataque de traversal de caminho (denominado “Vulnerabilidade aos 15 anos” quando redescoberto). Se um arquivo tar malicioso contiver entradas de ficheiros com ../ em seus nomes, extrair tudo escreveria alegremente ficheiros fora do diretório pretendido, potencialmente substituindo ficheiros críticos do sistema. Isso é rastreado como CVE-2007-4559. Embora seja um CVE antigo, ele continua sem correção na biblioteca padrão do Python até o momento da redação deste artigo, e pesquisas realizadas em 2022 mostraram centenas de milhares de repositórios ainda estão a usar arquivo tar de uma forma vulnerável.

Um invasor poderia carregar ou fornecer um arquivo tar especialmente criado para que, quando o seu código o extraísse, ele plantasse uma carga útil (por exemplo, um shell da web ou uma configuração sobrescrita) em um local ao qual o invasor não deveria ter acesso. Em uma demonstração, os pesquisadores exploraram isso para obter a execução do código, sobrescrevendo o próprio código de um pacote Python após a extração.

Não se trata apenas de ficheiros tar – problemas semelhantes podem ocorrer com ficheiros zip (vulnerabilidade zip slip) ou qualquer operação de ficheiro em que se constroem caminhos a partir de entradas externas. Sem verificações adequadas, uma entrada de arquivo chamada ../../../../../etc/passwd escreverá para /etc/passwd na extração.

Impacto: O percurso de caminho pode levar a gravação arbitrária de ficheiros (ou ler, em alguns casos) no servidor. Gravar ficheiros no local errado pode levar à execução de código – por exemplo, sobrescrever a configuração de uma aplicação para apontar para código controlado pelo invasor ou inserir um binário de Trojan no PATH. Mesmo que isso não leve imediatamente a RCE, sobrescrever ficheiros críticos pode sabotar a integridade do sistema ou facilitar ataques posteriores. Considere as consequências de um invasor sobrescrever a sua aplicação .env arquivo ou um script que é executado – eles poderiam inserir comandos maliciosos. No caso do CVE-2007-4559, a comunidade aumentou a sua gravidade quando ficou demonstrado que a execução de código é frequentemente uma consequência direta da exploração da sobregravação de arquivos.

Mitigação: Nunca extraia arquivos de fontes não confiáveis sem validação. Para tarfile, use tarfile.extractall(caminho, membros=...) e filtrar manualmente os membros. Pode implementar uma verificação para garantir que nenhum caminho de ficheiro dos membros esteja fora do diretório de destino (por exemplo, resolvendo caminhos absolutos e verificando padrões de travessia). A documentação do Python agora inclui um trecho de código para fazer isso com segurança – essencialmente rejeitando qualquer ficheiro com .. ou prefixos de unidade. Como alternativa, considere usar bibliotecas de terceiros que realizam extração segura. Para ficheiros zip, inspecione os nomes de forma semelhante antes de gravar ou use bibliotecas que mitigam o zip slip. Sempre com privilégios mínimos: se possível, execute a extração numa sandbox ou num diretório com permissões limitadas. Dessa forma, mesmo que uma exploração tente escapar, ela não poderá atingir ficheiros críticos do sistema.

Chamada Aikido : A análise estática Aikidopode detectar padrões perigosos, como tarfile.extractall() uso sem filtragem segura de membros. Ele conhece o CVE-2007-4559 e pode sinalizar instâncias no seu código em que você chama extractall ou extract sem precauções. Isso serve como um aviso para implementar as verificações adequadas. Além disso, o feed de inteligência de vulnerabilidades Aikido(sua pesquisa interna) acompanha essas questões "ocultas" em bibliotecas padrão e pacotes populares. Ao analisar o seu código e dependências, ele exibirá um aviso como “Possível traversal de caminho no uso do tarfile – considere validar o conteúdo do arquivo”, com um link para orientações sobre as melhores práticas. Em resumo, ele ajuda os programadores a detectar um bug de 15 anos que, de outra forma, poderia passar despercebido no seu código.

7. Utilização de bibliotecas desatualizadas com vulnerabilidades conhecidas (Requests, urllib3, etc.)

O rico ecossistema de pacotes do Python é um dos seus pontos fortes, mas cada dependência que você inclui também pode introduzir vulnerabilidades se não for mantida atualizada. Bibliotecas Python de alto perfil tiveram a sua cota de CVEs. Por exemplo, a biblioteca HTTP Requests, amplamente utilizada, teve bugs como:

  • CVE-2023-32681 – onde as solicitações vazariam credenciais de proxy HTTP em determinados cenários de redirecionamento, enviando Autorização por procuração cabeçalhos para servidores de destino e potencialmente expondo informações confidenciais informações(Isso foi corrigido na versão 2.31.0 do Requests.)
  • CVE-2024-35195 – uma falha lógica em que, se desativasse a verificação do certificado SSL uma vez numa sessão, as solicitações ignorariam persistentemente a verificação para solicitações subsequentes ao mesmo host, mesmo que tentasse reativá-la. Essencialmente, uma vez quebrado, sempre quebrado – uma surpresa desagradável que poderia silenciosamente deixar as ligações inseguras. Corrigido na versão 2.32.0.
  • Injeção CRLF no urllib3 – O urllib3 (usado pelo Requests nos bastidores) tinha uma vulnerabilidade que permitia a injeção CRLF em cabeçalhos HTTP se um invasor controlasse parte da URL ou do método da solicitação (por exemplo, caracteres de nova linha em um cabeçalho poderiam ser inseridos). Isso poderia ser usado indevidamente para contrabandear cabeçalhos ou dividir respostas, levando potencialmente ao sequestro de sessão ou à manipulação de caches da web. (Vários CVEs, por exemplo, CVE-2019-9740 para o urllib integrado do Python, foram atribuídos a tais problemas.)

Estes são apenas alguns exemplos. Outros exemplos notáveis incluem vulnerabilidades em Análise de URL (por exemplo, CVE-2023-24329, um problema em urllib.parse que permitia aos invasores contornar listas de bloqueio de URLs usando uma URL complicada que começava com um espaço ou caractere de controlo) e problemas em gestão de pacotes ferramentas (como a vulnerabilidade CVE-2018-20225 do pip, que permitia que um download malicioso sobrescrevesse ficheiros arbitrários). Mesmo bibliotecas de dados populares (Pandas, NumPy) ocasionalmente têm correções de segurança (geralmente problemas de DoS ou corrupção de memória).

Impacto: As vulnerabilidades conhecidas nas bibliotecas podem ter uma ampla gama de impactos — desde fuga de informações e negação de serviço até comprometimento total — dependendo do bug. O ponto principal é que os invasores procuram ativamente por aplicações que utilizam versões desatualizadas. Se estiver a utilizar uma versão antiga do Requests e a sua aplicação fizer chamadas de rede, um invasor poderá explorar a fuga de autenticação do proxy para roubar credenciais. Ou, se tiver uma versão desatualizada do urllib3, eles poderão explorar a injeção CRLF para comprometer as suas interações HTTP. Como essas vulnerabilidades são públicas, os invasores sabem exatamente o que procurar. Não atualizar as dependências é como deixar falhas conhecidas sem correção na sua aplicação.

Mitigação: Mantenha-se a par das atualizações de dependências e avisos de segurança. Use ferramentas para verificar se há CVEs conhecidos nas suas dependências (pip-tools, Dependabot do GitHub ou SCA comerciais SCA ). Quando um novo CVE crítico for anunciado (por exemplo, um bug grave no Django, Flask, Requests, etc.), priorize a atualização para uma versão corrigida. Sempre que possível, fixe as suas dependências em versões conhecidas como boas e revise os registos de alterações das atualizações. Considere também fixações de versão mínima: por exemplo, exigir solicitações>=2.31.0 se você sabe que os mais antigos são vulneráveis. Além disso, empregue uma defesa em profundidade: por exemplo, mesmo que o Requests tivesse um bug de verificação de certificado, você poderia adicionar uma camada de segurança de rede (como interceção TLS ou fixação adicional de certificado) para mitigar o risco. Mas o mais simples é: mantenha os seus pacotes atualizados.

AlertaAikido : É aqui que análise de composição de software SCA) da Aikido em ação. O scanner de dependências Aikidoverifica continuamente os requisitos do seu projeto (e até mesmo as suas dependências transitivas) em relação a um banco de dados de vulnerabilidades conhecidas. Ele irá alertá-lo: “A biblioteca X versão Y é vulnerável ao CVE-2023-32681”, muitas vezes fornecendo detalhes e uma versão corrigida recomendada. Melhor ainda, a plataforma Aikidopode fazer correções automatizadas – por exemplo, abrir uma solicitação pull para atualizar uma versão. Ao integrar isso ao seu CI/CD, você garante que não está a implementar contentores ou aplicações com bibliotecas desatualizadas. Em resumo, ferramentas como Aikido detectar CVEs conhecidas e até mesmo corrigi-las automaticamente, complementando scanners de código aberto com regras personalizadas e informações atualizadas.

8. Desativação de recursos de segurança (por exemplo, ignorar a validação do certificado SSL)

Às vezes, durante o desenvolvimento ou teste, os engenheiros desativam verificações de segurança importantes – e, então, o código é enviado para produção dessa forma. Um exemplo clássico em Python é fazer solicitações HTTP com Verificação SSL desativada. A biblioteca Requests (e outras semelhantes, como urllib3) permitem um verificar=Falso sinalizador para ignorar erros de certificado SSL. Isso é conveniente ao lidar com certificados autoassinados em um ambiente de desenvolvimento, mas se isso chegar à produção, expone você a ataques man-in-the-middle (MitM). A documentação do Requests avisa explicitamente: quando verificar=Falso, o cliente aceitará qualquer certificado – ignorando incompatibilidades de nomes de host ou certificados expirados/autoassinados – tornando a sua aplicação vulnerável a ataques MITM. Essencialmente, você não confirma mais que está a falar com o servidor real. Um invasor poderia interceptar o seu tráfego (especialmente se puder falsificar o DNS ou estiver na mesma rede) e apresentar qualquer certificado para sequestrar a ligação.

Além da verificação SSL, outros recursos desativados também podem prejudicá-lo: por exemplo, usar HTTP em vez de HTTPS para comunicações confidenciais, desativar manualmente a verificação do nome do host TLS ou desativar as redes de segurança integradas do Python (como executar o interpretador com as asserções desativadas, se essas asserções estivessem protegendo uma verificação crítica para a segurança).

Impacto: se um invasor conseguir se infiltrar no seu tráfego (o que é mais fácil do que muitos pensam, especialmente em container de nuvem ou container , ou Wi-Fi público, etc.), ele poderá descriptografar e modificar os dados em trânsito quando a verificação de certificado estiver desativada. Isso pode significar que um invasor roube tokens de API, injete respostas maliciosas ou se faça passar por serviços. Numa arquitetura de microsserviços, um serviço comprometido ou uma posição de rede comprometida pode permitir a pivotação, interceptando chamadas de um serviço para outro, se essas chamadas não forem devidamente verificadas. Também vimos cenários em que desativar a verificação SSL em uma biblioteca de clientes API permitiu que invasores servissem malware a partir do que deveria ser um servidor de atualização confiável, simplesmente usando um certificado autoassinado em um domínio falsificado. As consequências podem ser roubo de dados, invasão de contas ou injeção de dados/comandos maliciosos no funcionamento do seu aplicativo.

Mitigação: Nunca desative a verificação SSL no código de produção. Se for realmente necessário (por exemplo, para se conectar a um serviço interno com um certificado autoassinado), pelo menos fixe o certificado ou a impressão digital para não confiar cegamente em nenhum certificado. Melhor ainda, use uma CA privada e torne os seus certificados internos confiáveis, fornecendo o pacote da CA. Durante o desenvolvimento, se você usar verificar=Falso, tenha muito cuidado ao removê-lo antes de confirmar ou use a configuração para desativá-lo apenas em ambientes que não sejam de produção. As revisões de código devem tratar verificar=Falso como um grande sinal de alerta. Além disso, considere usar ferramentas como linters para proibir esse sinal no código confirmado. O mesmo se aplica a outros atalhos – por exemplo, não capture e ignore exceções de segurança, não desative a autenticação ou CSRF na depuração e se esqueça de reativar, etc.

Chamada Aikido : Os scanners Aikidopodem detetar o uso de configurações arriscadas, como verificar=Falso nas solicitações. Na verdade, ele pode aplicar políticas (semelhantes ao funcionamento das políticas Prisma/Checkov) para garantir que nenhum código desative as verificações de certificado. Se tal padrão for encontrado, Aikido indicá-lo nos resultados da verificação, tratando-o como uma vulnerabilidade. Ele poderá indicar “Verificação de certificado SSL desativada aqui – isto não deve ser usado em produção” com um link para a linha de código. Ao integrar isso na CI, evita eficazmente o cenário «Deixei uma bandeira de depuração ativada». Além disso, a análise de dependências mencionada anteriormente também o análise de dependências sobre bugs como o CVE-2024-35195, onde mesmo a desativação não intencional persiste – destacando que precisa de atualizar a sua biblioteca para restaurar totalmente a segurança.

9. Pacotes maliciosos ou comprometidos ( ataques à Supply chain de software ataques à Supply chain)

Nem todas as ameaças vêm de erros no seu próprio código – às vezes, o código que você extraiu do próprio PyPI é o ataque. ataques à Supply chain através de pacotes Python maliciosos aumentaram nos últimos anos. Os atacantes publicam pacotes com erros ortográficos ou totalmente falsos no PyPI, nomeando-os de forma semelhante a bibliotecas populares (por exemplo, pedidos em vez de pedidos) ou nomes apelativos como free-net-vpn. Desenvolvedores desavisados instalam-nos, e o código malicioso é executado durante a instalação (em setup.py) ou após a importação. Por exemplo, em 2022, foram descobertos dez pacotes PyPI maliciosos que bibliotecas comuns falsificadas e injetou malware para roubo de informações nos sistemas dos desenvolvedores. Um pacote, imitando um pacote bem conhecido, foi projetado para procurar credenciais da AWS e enviá-las a um invasor por meio de um webhook do Discord. Outro chamado WINRPCexploit afirmava ser uma ferramenta de exploração, mas na verdade exfiltrava todas as variáveis de ambiente (frequentemente contendo secrets) para o invasor.

Mesmo pacotes legítimos podem ser comprometidos se um invasor obtiver acesso à conta do mantenedor (como aconteceu com o event-stream no Node.js e também aconteceu no Python). Houve casos em que pacotes amplamente utilizados foram brevemente sequestrados para incluir código malicioso em novas versões. Por exemplo, um pacote pode de repente começar a enviar telemetria de uso (espionagem) ou incluir um backdoor acionado sob certas condições.

Impacto: O impacto de pacotes maliciosos pode ser grave e de longo alcance. Como esses pacotes geralmente executam código no momento da instalação (por meio de scripts de configuração) ou quando importados, eles podem fazer tudo o que o utilizador pode fazer: roubar credenciais (de ficheiros de configuração, variáveis de ambiente, configuração da AWS CLI etc.), instalar trojans, encriptar ficheiros (ransomware) ou abrir shells reversos. E como eles geralmente são executados com privilégios de desenvolvedor, podem comprometer não apenas o aplicativo, mas todo o sistema ou as credenciais que o desenvolvedor possui. Em um pipeline de CI, um pacote corrompido pode extrair secrets seu ambiente de CI. Em um ambiente de produção, uma dependência maliciosa pode se tornar uma porta dos fundos para que invasores continuem a explorar. ataques à Supply chain particularmente insidiosos porque minam a confiança nas próprias ferramentas que usamos.

Mitigação: Analise e monitore cuidadosamente as suas dependências. Algumas práticas recomendadas: Fixe dependências em versões específicas (para não baixar automaticamente uma atualização adulterada). Verifique as somas de verificação ou assinaturas dos pacotes (o PyPI agora suporta assinatura GPG e similares, embora nem todos os pacotes a utilizem). Use ferramentas como pip install --no-build-isolation --only-binary=:all: para rodas conhecidas como boas, a fim de evitar a execução do setup.py de pacotes desconhecidos. Considere empregar um proxy ou espelho PyPI local e permitir apenas a passagem de pacotes verificados. Leia sempre os detalhes do pacote: se pedidos tem 100 milhões de downloads e, de repente, surge um novo pedidos pacote – isso é suspeito. Os recursos de segurança do PyPI (como 2FA para mantenedores) estão a melhorar, mas a responsabilidade também recai sobre os utilizadores: não instale pacotes aleatórios sem análise prévia. Se possível, analise a origem das novas dependências (pelo menos uma verificação rápida para padrões maliciosos óbvios, como os.system('curl ...')).

Chamada Aikido : A plataforma Aikidoaborda os riscos da cadeia de abastecimento de várias maneiras. Primeiro, o seu análise de dependências marcará pacotes que são conhecidos como malware ou que apresentam comportamento suspeito. Aikido ingere Aikido Threat Intelligence indicadores de pacotes maliciosos) e pode alertá-lo, «O pacote X foi reportado como malicioso – não o utilize.» Em segundo lugar, Aikido (uma ferramenta de código aberto da Aikido) pode impedir a instalação de pacotes não confiáveis. Essencialmente, bloqueia pacotes que não têm tempo suficiente ou que aparecem repentinamente na sua árvore de dependências, mitigando ataques de typosquatting ao exigir um período de "reflexão" (por exemplo, instalar apenas pacotes que existem há mais de 24 horas, para evitar malware recém-publicado). Ao integrar essas defesas, adiciona um watchdog automatizado sempre que faz instalar pip. Na prática, Aikido garantir que as bibliotecas das quais você depende não o traiam – capturando agentes maliciosos conhecidos e aplicando políticas para dificultar a entrada de novos agentes.

10. Práticas de criptografia fracas (aleatoriedade insuficiente e uso inadequado de criptografia)

A criptografia é complexa e utilizá-la incorretamente pode comprometer a segurança tanto quanto um bug evidente. Em Python, um erro comum é utilizar o gerador de números aleatórios errado para contextos sensíveis à segurança. Por exemplo, os programadores podem utilizar aleatório.aleatório() ou random.randrange() para gerar um token de redefinição de palavra-passe ou ID de sessão. No entanto, o padrão aleatório módulo é não é criptograficamente seguro – utiliza algoritmos previsíveis que não são adequados para a geração de segredos. O Python introduziu o secrets módulo por esse motivo, afirmando que secrets deve ser usado para aleatoriedade crítica para a segurança, em vez do gerador de números pseudoaleatórios padrão no aleatório módulo, que foi concebido para modelação e simulação, e não para segurança ou criptografia. Se utilizar aleatório para tokens, um invasor pode ser capaz de prever valores (com observações suficientes ou conhecimento da semente).

Outra prática ineficaz é usar algoritmos desatualizados ou fracos. Por exemplo, usar MD5 ou SHA1 para hash de senhas (ambos são considerados ineficazes para essa finalidade) ou não adicionar salt às senhas. Ou criar a sua própria «criptografia» (por exemplo, um esquema XOR caseiro) em vez de usar bibliotecas comprovadas. Essas fraquezas podem não se manifestar como um CVE no seu código, mas reduzem significativamente a dificuldade para os invasores. Um exemplo real: se as palavras-passe forem armazenadas sem sal com SHA-1, um invasor que rouba a base de dados de hash pode quebrar a maioria das palavras-passe rapidamente usando tabelas rainbow pré-calculadas.

Impacto: A aleatoriedade insegura pode levar ao sequestro de contas ou à falsificação de tokens. Imagine que um invasor adivinhe os cookies de sessão porque eles foram derivados de uma saída PRNG previsível — isso não é apenas teoria, já aconteceu em sistemas mal projetados. Hash ou criptografia fracos significam que, se um invasor violar uma camada (por exemplo, obtiver acesso de leitura a um banco de dados ou interceptar tráfego criptografado), ele poderá facilmente descriptografar ou quebrar os dados supostamente protegidos. No geral, uma criptografia fraca dá uma falsa sensação de segurança; os invasores podem não precisar de uma “exploração” quando podem simplesmente usar força bruta ou prever o que precisam.

Mitigação: Siga a corrente melhores práticas criptográficas. Utilize o secrets módulo ou os.urandom() para gerar quaisquer tokens secretos, chaves ou nonces. Use bibliotecas de alto nível para criptografia (como Fernet no criptografia biblioteca) em vez de escrever a sua própria criptografia. Para armazenamento de senhas, use KDFs estabelecidos (bcrypt, Argon2, PBKDF2 com iterações adequadas) – nunca use hashes simples sem salt. Mantenha os algoritmos atualizados; por exemplo, SHA-256 é bom para integridade, mas para senhas você ainda vai querer um hash lento como bcrypt. E sempre habilite o TLS para comunicação de rede, usando protocolos modernos (TLS 1.2+). Essencialmente, opte por implementações bem testadas em vez de abordagens personalizadas ou legadas. Além disso, fique atento às descontinuações: se uma configuração ou cifra SSL/TLS não for mais recomendada (o módulo ssl do Python geralmente atualiza os padrões, mas tenha cuidado ao substituir as configurações).

Chamada Aikido : SAST Aikido SAST ajudar a identificar alguns erros comuns em criptografia – por exemplo, ele pode alertar se detectar o aleatório módulo a ser utilizado onde secrets seria apropriado, ou se encontrar o MD5 a ser usado num contexto de segurança. Além disso, a inteligência de vulnerabilidade Aikidoirá alertá-lo se estiver a usar um algoritmo conhecido como fraco num contexto que teve CVEs anteriores (por exemplo, se uma biblioteca que usa tiver como padrão um modo inseguro, Aikido indicar isso). Embora a supervisão humana seja crucial na criptografia, ter uma ferramenta automatizada para verificar novamente não faz mal. É como um linter para segurança: se você inadvertidamente cometer token = random.random(), uma ferramenta pode perguntar: «Tem a certeza? Isto não é criptograficamente seguro.» Esse tipo de feedback precoce pode orientar os programadores para os módulos certos (talvez até sugerindo: importar secrets e secrets.token_hex() como alternativa). Em suma, Aikido a reforçar a higiene criptográfica, detectando padrões fracos óbvios e mantendo-o informado sobre vulnerabilidades relacionadas com a criptografia no ecossistema.

Conclusão: proteja o seu código Python desde o início

A flexibilidade e o rico ecossistema do Python podem ser uma faca de dois gumes: poderosos nas mãos dos programadores, mas oferecendo muitas oportunidades para invasores se não forem tomadas as devidas precauções. Explorámos como coisas como execução dinâmica de código, vulnerabilidades de injeção, vazamento secrets, dependências desatualizadas e outras armadilhas podem comprometer a segurança das suas aplicações Python. A boa notícia é que cada uma dessas falhas pode ser evitada com uma combinação de melhores práticas e as ferramentas certas:

  • Adote práticas de codificação seguras: valide entradas, evite funções perigosas e use padrões seguros (por exemplo, carregadores seguros, aleatórios seguros, algoritmos atualizados).
  • Mantenha as suas dependências atualizadas e verificadas: não deixe CVEs conhecidas permanecerem nos seus requisitos e tenha cuidado com o que instala.
  • Integre a segurança ao seu pipeline de desenvolvimento: isso significa executar análises estáticas, varreduras de segredos e auditorias de dependências enquanto você codifica e durante a integração contínua, não após um incidente.

DevSecOps modernas DevSecOps , como Aikido podem facilitar muito esse processo, automatizando a deteção desses problemas — desde capturar uma palavra-passe codificada antes que ela saia do seu portátil, até bloquear a implementação de um pacote vulnerável e alertá-lo sobre uma falha recém-divulgada em uma das suas bibliotecas. Conforme observado no relatório container da Red Hat, quase metade das equipas perde o sono por causa container segurança container e, por extensão, de software) — o mesmo provavelmente se aplica à segurança de aplicações Python. Ao mudar a segurança para a esquerda — ou seja, abordá-la no início do desenvolvimento —, pode reduzir significativamente as hipóteses de uma emergência noturna causada por um bug Python evitável.

Em resumo, manter-se informado e proativo é fundamental. Continue a aprender sobre codificação segura (o Guia de Segurança Python e os recursos OWASP são ótimos), incentive revisões de código com a segurança em mente e aproveite as ferramentas automatizadas como sua rede de segurança. Os programadores Python que incorporam a segurança desde o início pouparão tempo, dinheiro e reputação às suas organizações a longo prazo. Vamos escrever código que não seja apenas inteligente e limpo, mas também seguro e protegido. O seu eu futuro (e os seus utilizadores) agradecerão por isso.

Continue a ler:
As 9 principais vulnerabilidades Container Docker    
As 7 principais vulnerabilidades Cloud    
As 10 principais vulnerabilidades de segurança de aplicações web que todas as equipas devem conhecer    
As 9 principais segurança Kubernetes e configurações incorretas segurança Kubernetes    
Principais vulnerabilidades de segurança de código encontradas em aplicações modernas    As principais vulnerabilidades de segurança JavaScript em aplicações web modernas    
As 9 principais segurança da supply chain de software explicadas

4.7/5

Proteja seu software agora

Comece Gratuitamente
Não é necessário cc
Agendar uma demonstração
Seus dados não serão compartilhados · Acesso somente leitura · Não é necessário cartão de crédito

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.