
Fork do .NET 7 do seal-security-nuget-demo: mesma história de exploit CVE-2024-21907, redirecionado para clientes presos ao .NET SDK 7.
Este é um fork redirecionado do fork canónico seal-security-nuget-demo (que tem como alvo net9.0). A história do exploit, os controladores e a lista de pacotes selados são idênticos — apenas o TargetFramework difere.
Existe porque a maioria dos clientes empresariais não consegue migrar para o SDK .NET mais recente a pedido. O .NET 7 atingiu o fim do suporte em 14 de maio de 2024, mas muitos ambientes de produção ainda o utilizam por questões de compatibilidade, certificação ou razões operacionais. Este é precisamente o caso para o qual a Seal Security foi concebida: quando um cliente não pode (ou não quer) fazer uma atualização de versão major, a Seal corrige a dependência vulnerável no local sob a mesma versão, sem alterações na API pública e sem edições de código na aplicação do cliente. Esta demonstração permite que essa conversa aconteça na stack real do cliente, em vez de pedir que instale net8/net9 primeiro.
O fork fixa o SDK em 7.0.x através de global.json para que atualizações acidentais não entrem durante a demonstração.
Esta aplicação de demonstração é uma página de boas-vindas ASP.NET Core simples que utiliza Newtonsoft.Json 12.0.2 para analisar a entrada do utilizador como um objeto de configuração. A aplicação tem um campo de nome — escreva o seu nome, clique em Go, e mostra "Welcome, alice!". Internamente, passa a entrada por JsonConvert.DeserializeObject<NestedConfig>() do Newtonsoft.Json. É isso — uso completamente padrão de uma biblioteca JSON popular.
O problema é que o Newtonsoft.Json 12.0.2 (e versões anteriores a 13.0.1) tem CVE-2024-21907 — uma vulnerabilidade de Negação de Serviço de alta gravidade com uma pontuação CVSS de 7.5 (ALTA). Esta demonstração mostra como a Seal Security corrige a vulnerabilidade no local sem exigir uma atualização de versão major.
O método JsonConvert.DeserializeObject<T>() do Newtonsoft.Json pode ser explorado ao criar payloads JSON profundamente aninhados. Ao desserializar para um objeto tipado (POCO), o JsonSerializerInternalReader da biblioteca realiza chamadas verdadeiramente recursivas (CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue → CreateValueInternal) que causam stack overflow, levando a uma falha da aplicação (Negação de Serviço).
A aplicação recebe a entrada do utilizador e processa-a através do Newtonsoft.Json. Se a entrada for um URL, a aplicação primeiro obtém o conteúdo — um padrão realista usado por carregadores de configuração, testadores de API e recetores de webhook:
public class NestedConfig
{
[JsonProperty("n")]
public NestedConfig? N { get; set; }
}
var config = JsonConvert.DeserializeObject<NestedConfig>(name);
Entrada normal: Escreva alice → mostra "Welcome, alice!"
Exploit: Cole este URL no campo de nome e clique em Go:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
A aplicação deteta que é um URL, obtém o json-payload (JSON profundamente aninhado {"n":{"n":{...}}}) e desserializa-o através do Newtonsoft.Json na classe recursiva NestedConfig — desencadeando o stack overflow.
O JsonSerializerInternalReader percorre recursivamente CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue para cada nível de aninhamento. A cerca de ~5.000 níveis de profundidade, esgota a stack da thread e a aplicação falha com uma StackOverflowException — o processo morre instantaneamente (não é possível um tratamento de erro gracioso).
Com esta vulnerabilidade, os atacantes podem:
A correção publicamente disponível exige a atualização para a versão 13.0.1. No entanto, atualizar versões major introduz frequentemente:
Isto torna a correção "simplesmente atualizar" um projeto que pode facilmente levar semanas de tempo de desenvolvimento — deixando a vulnerabilidade aberta entretanto.
A versão patcheada da Seal (12.0.2-sp1) adiciona proteção de profundidade de recursão sem alterar qualquer API pública. O patch:
MaxDepth predefinidos para evitar recursão ilimitadaEsta é a mesma estratégia de mitigação aplicada no Newtonsoft.Json 13.0.1, retroportada para 12.0.2 como uma substituição direta.
Esta demonstração também inclui outros pacotes NuGet vulneráveis que a Seal Security pode corrigir:
Vulnerabilidade de Entidade Externa XML (XXE) na análise do ficheiro de configuração XML do log4net. Um atacante que consiga controlar o ficheiro de configuração log4net pode:
Nota sobre
System.Net.Http: A demonstração canónica net9 também inclui uma referência vulnerável aSystem.Net.Http 4.3.0para CVE-2017-0249. Omitimo-la deste fork net7 porque no .NET 7System.Net.Httpfaz parte da BCL e a referência de pacote autónoma é um meta-pacote vestigial — tem casos extremos conhecidos comdotnet add package --source <local-nupkg>, que é exatamente como a Seal CLI aplica versões seladas. Removê-la torna o passoseal fixfiável sem alterar a história da demonstração (HttpClientcontinua a funcionar bem; o runtime fornece-o).
Os binários da CLI para Windows foram descontinuados após v0.3.238. A v0.3.238 é totalmente funcional para remediação NuGet no Windows.
Um guia detalhado de instalação e execução no Windows Server está em README-WINDOWS-SERVER.md. O Quick Start abaixo abrange os mesmos passos de forma condensada.
PowerShell:
$env:SEAL_TOKEN = "your-seal-token-here"
$env:SEAL_PROJECT = "nuget-demo-net7"
cd seal-security-nuget-demo-net7
# Restauro (obtém de nuget.org e do feed da Seal — ver nuget.config)
dotnet restore
# Compilar e executar
dotnet build
dotnet run
Abra http://localhost:5000 — a aplicação está a executar com dependências vulneráveis.
Escreva alice no campo de nome, clique em Go. Deverá ver: "Welcome, alice!"
Cole o seguinte URL no campo de nome e clique em Go:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
Resultado não patcheado: O navegador mostra um erro / reset da conexão — a aplicação crashou com uma StackOverflowException em JsonSerializerInternalReader.CreateValueInternal. O processo morreu.
# (Opcional — já feito acima) Restaurar dependências primeiro
dotnet restore
# Executar a CLI da Seal para corrigir vulnerabilidades
seal fix . --mode remote -v
# Restauro novamente para obter versões seladas
dotnet restore
# Compilar e executar a aplicação patcheada
dotnet build
dotnet run
A aplicação agora usa versões patcheadas (Newtonsoft.Json 12.0.2-sp1, log4net 2.0.5-sp1).
Resultado patcheado: Cole o mesmo URL de exploit → a página mostra "Blocked by Seal patch: MaxDepth of 64 has been exceeded." — o limite de recursão patcheado do Newtonsoft.Json rejeitou o payload profundo. O servidor continua a executar normalmente.
dotnet list package
Deverá ver pacotes com sufixo -sp1 indicando patches da Seal Security.
O passo da CLI deve ser adicionado imediatamente após as dependências serem instaladas mas antes da compilação final.
# 1. Restaurar dependências
dotnet restore
# 2. <--- Executar a CLI da Seal Aqui
$env:SEAL_TOKEN = "your-seal-token-here"
$env:SEAL_PROJECT = "nuget-demo-net7"
seal fix . --mode remote -v
# 3. Restaurar novamente (para obter versões seladas)
dotnet restore
# 4. Compilar
dotnet build
| Modo | Descrição |
|---|---|
all | Aplicar automaticamente todas as correções disponíveis |
remote | Aplicar apenas correções aprovadas na UI da Seal |
local | Aplicar apenas correções definidas em .seal-actions.yml |
.seal-actions.yml neste repositório já lista as três substituições seladas para o modo local, portanto seal fix . --mode local -v funciona offline (ainda precisa do token para o servidor de artefactos).
O nuget.config está pré-configurado para usar a Seal Security com variáveis de ambiente:
<configuration>
<packageSources>
<add key="Seal" value="https://nuget.sealsecurity.io/v3/index.json" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageSourceCredentials>
<Seal>
<add key="Username" value="%SEAL_PROJECT%" />
<add key="ClearTextPassword" value="%SEAL_TOKEN%" />
</Seal>
</packageSourceCredentials>
</configuration>
| Variável | Descrição |
|---|---|
SEAL_TOKEN | O seu token de acesso da Seal Security |
SEAL_PROJECT | ID do projeto (ex.: nuget-demo-net7) |
A CLI da Seal precisa de HTTPS de saída (TCP 443) para:
cli.sealsecurity.io — configuração de scan / fixauthorization.sealsecurity.io — validação de tokennuget.sealsecurity.io — transferências de .nupkg seladosd2zko6i8myndc4.cloudfront.net — CDN que serve os artefactos selados reais (os hostnames .sealsecurity.io redirecionam para aqui)api.nuget.org / endpoints padrão do nuget.org — para dependências não seladasVerifique a partir do PowerShell após a firewall estar aberta:
Test-NetConnection cli.sealsecurity.io -Port 443
Test-NetConnection authorization.sealsecurity.io -Port 443
Test-NetConnection nuget.sealsecurity.io -Port 443
Test-NetConnection d2zko6i8myndc4.cloudfront.net -Port 443
Todos devem reportar TcpTestSucceeded: True.
12.0.2-sp1 é uma substituição binária compatível para 12.0.2.Pacotes usados por esta demonstração:
| Pacote | Versão Vulnerável | Versão Selada | CVE | CVSS |
|---|
Outros pacotes NuGet selados disponíveis no feed da Seal (não nesta demonstração, listados para referência):
Licença MIT — Consulte o ficheiro LICENSE para mais detalhes.
| Item | Porque é importante |
|---|
global.json fixa o SDK em 7.0.x com rollForward: latestFeature | Impede que máquinas com net8/net9 lado a lado mudem silenciosamente de SDK durante a demonstração. |
System.Configuration.ConfigurationManager fixado em 7.0.0 | A demonstração canónica net9 usa 8.0.0, que tem como alvo apenas net8 e falha ao restaurar em net7. O 7.0.0 tem a mesma superfície de API que o log4net precisa. |
NU1701 suprimido no csproj | O log4net 2.0.5 anuncia um TFM net4x legado que o .NET 7 aceita em tempo de execução, mas avisa durante o restauro. O aviso é cosmético; a supressão mantém a saída de compilação limpa durante a demonstração. |
| Seal CLI v0.3.238 para Windows x64 | Última versão com binário Windows; totalmente funcional para remediação NuGet. Os binários Windows foram descontinuados após esta versão, por isso não sugira uma versão mais recente. |
| Newtonsoft.Json | 12.0.2 | 12.0.2-sp1 | CVE-2024-21907 | 7.5 ALTA |
| log4net | 2.0.5 | 2.0.5-sp1 | CVE-2018-1285 | 9.8 CRÍTICO |
| Pacote | Versão Vulnerável | Versão Selada | CVE | CVSS |
|---|
| log4net | 2.0.0 | 2.0.0-sp1 | CVE-2018-1285 | 9.8 CRÍTICO |
| System.Net.Http | 4.3.0 | 4.3.0-sp1 | CVE-2017-0249 | 7.3 ALTA |
| Snappier | 1.1.0 | 1.1.0-sp1 | CVE-2023-28638 | 7.0 ALTA |
| jQuery.Validation | 1.17.0 | 1.17.0-sp1 | CVE-2021-21252 | 7.5 ALTA |