
.NET 7 fork do seal-security-nuget-demo: mesma história de exploração do CVE-2024-21907, redirecionado para clientes bloqueados no .NET SDK 7.
Este é um fork redirecionado do seal-security-nuget-demo canônico (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.
Ele existe porque a maioria dos clientes empresariais não pode migrar para o SDK .NET mais recente sob demanda. O .NET 7 atingiu o fim do suporte em 14 de maio de 2024, mas ambientes de produção reais ainda o utilizam por motivos de compatibilidade, certificação ou operacionais. Esse é exatamente o caso para o qual a Seal Security foi projetada: quando um cliente não pode (ou não quer) fazer um upgrade de versão principal, a Seal corrige a dependência vulnerável no lugar sob a mesma versão, sem mudança de API pública e sem edições de código no aplicativo do cliente. Esta demonstração permite que essa conversa aconteça na stack real do cliente, em vez de pedir que ele instale net8/net9 primeiro.
O fork fixa o SDK em 7.0.x via global.json para que upgrades acidentais não entrem sorrateiramente durante a demonstração.
Este aplicativo de demonstração é uma página de boas-vindas ASP.NET Core simples que usa Newtonsoft.Json 12.0.2 para analisar a entrada do usuário como um objeto de configuração. O aplicativo tem um campo de nome — digite seu nome, clique em Go, e ele exibe "Welcome, alice!". Nos bastidores, ele passa a entrada pelo 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 à 13.0.1) tem CVE-2024-21907 — uma vulnerabilidade de Negação de Serviço de alta gravidade com pontuação CVSS de 7.5 (ALTA). Esta demonstração mostra como a Seal Security corrige a vulnerabilidade no lugar, sem exigir um upgrade de versão principal.
O método JsonConvert.DeserializeObject<T>() do Newtonsoft.Json pode ser explorado criando payloads JSON profundamente aninhados. Ao desserializar em um objeto tipado (POCO), o JsonSerializerInternalReader da biblioteca realiza chamadas verdadeiramente recursivas (CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue → CreateValueInternal) que causam estouro de pilha, levando à falha do aplicativo (Negação de Serviço).
O aplicativo recebe a entrada do usuário e a analisa através do Newtonsoft.Json. Se a entrada for uma URL, o aplicativo busca o conteúdo primeiro — um padrão realista usado por carregadores de configuração, testadores de API e receptores de webhook:
public class NestedConfig
{
[JsonProperty("n")]
public NestedConfig? N { get; set; }
}
var config = JsonConvert.DeserializeObject<NestedConfig>(name);
Entrada normal: Digite alice → exibe "Welcome, alice!"
Exploit: Cole esta URL no campo de nome e clique em Go:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
O aplicativo detecta que é uma URL, busca o json-payload (JSON profundamente aninhado {"n":{"n":{...}}}) e o desserializa através do Newtonsoft.Json na classe recursiva NestedConfig — acionando o estouro de pilha.
O JsonSerializerInternalReader recorre através de CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue para cada nível de aninhamento. A cerca de ~5.000 níveis de profundidade, isso esgota a pilha de threads e o aplicativo falha com uma StackOverflowException — o processo morre instantaneamente (nenhum tratamento de erro gracioso é possível).
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 principais frequentemente introduz:
Isso torna a correção "apenas atualize" um projeto que pode facilmente levar semanas de tempo de desenvolvedor — deixando a vulnerabilidade aberta nesse meio tempo.
A versão corrigida da Seal (12.0.2-sp1) adiciona proteção de profundidade de recursão sem mudar nenhuma API pública. A correção:
MaxDepth para prevenir recursão ilimitadaEsta é a mesma estratégia de mitigação aplicada no Newtonsoft.Json 13.0.1, portada de volta para 12.0.2 como uma substituição drop-in.
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 de configuração XML do log4net. Um atacante que possa controlar o arquivo de configuração do log4net pode:
Nota sobre
System.Net.Http: A demonstração net9 canônica também inclui uma referência vulnerável aSystem.Net.Http 4.3.0para CVE-2017-0249. Nós a omitimos deste fork net7 porque no .NET 7 oSystem.Net.Httpfaz parte do BCL e a referência de pacote independente é um meta-pacote vestigial — ele tem casos de borda conhecidos comdotnet add package --source <local-nupkg>, que é exatamente como o CLI da Seal aplica versões seladas. Removê-lo torna a etapaseal fixconfiável sem mudar a história da demonstração (HttpClientcontinua funcionando bem; o runtime o fornece).
Os binários do CLI para Windows foram descontinuados após a 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 cobre os mesmos passos de forma condensada.
PowerShell:
$env:SEAL_TOKEN = "seu-token-seal-aqui"
$env:SEAL_PROJECT = "nuget-demo-net7"
cd seal-security-nuget-demo-net7
# Restaurar (puxa do nuget.org e do feed da Seal — veja nuget.config)
dotnet restore
# Compilar e executar
dotnet build
dotnet run
Abra http://localhost:5000 — o aplicativo está rodando com dependências vulneráveis.
Digite alice no campo de nome, clique em Go. Você deve ver: "Welcome, alice!"
Cole a seguinte URL no campo de nome e clique em Go:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
Resultado sem correção: O navegador mostra um erro / conexão redefinida — o aplicativo falhou com uma StackOverflowException em JsonSerializerInternalReader.CreateValueInternal. O processo está morto.
# (Opcional — já feito acima) Restaurar dependências primeiro
dotnet restore
# Executar o CLI da Seal para corrigir vulnerabilidades
seal fix . --mode remote -v
# Restaurar novamente para puxar as versões seladas
dotnet restore
# Compilar e executar o aplicativo corrigido
dotnet build
dotnet run
O aplicativo agora usa versões corrigidas (Newtonsoft.Json 12.0.2-sp1, log4net 2.0.5-sp1).
Resultado corrigido: Cole a mesma URL de exploit → a página mostra "Blocked by Seal patch: MaxDepth of 64 has been exceeded." — o limite de recursão corrigido do Newtonsoft.Json rejeitou o payload profundo. O servidor continua rodando normalmente.
dotnet list package
Você deve ver pacotes com o sufixo -sp1 indicando as correções da Seal Security.
A etapa do CLI deve ser adicionada imediatamente após a instalação das dependências mas antes da compilação final.
# 1. Restaurar dependências
dotnet restore
# 2. <--- Executar o CLI da Seal Aqui
$env:SEAL_TOKEN = "seu-token-seal-aqui"
$env:SEAL_PROJECT = "nuget-demo-net7"
seal fix . --mode remote -v
# 3. Restaurar novamente (para obter as versões seladas)
dotnet restore
# 4. Compilar
dotnet build
| Modo | Descrição |
|---|---|
all | Aplicar todas as correções disponíveis automaticamente |
remote | Aplicar apenas correções aprovadas na interface da Seal |
local | Aplicar apenas correções definidas em .seal-actions.yml |
O .seal-actions.yml neste repositório já lista as três substituições seladas para o modo local, então seal fix . --mode local -v funciona offline (ainda precisa do token para o servidor de artefatos).
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 | Seu token de acesso da Seal Security |
SEAL_PROJECT | ID do projeto (ex.: nuget-demo-net7) |
O CLI da Seal precisa de HTTPS de saída (TCP 443) para:
cli.sealsecurity.io — configuração de scan / correçãoauthorization.sealsecurity.io — validação de tokennuget.sealsecurity.io — downloads de .nupkg seladosd2zko6i8myndc4.cloudfront.net — CDN que serve os artefatos selados reais (os hostnames .sealsecurity.io redirecionam para cá)api.nuget.org / endpoints padrão do nuget.org — para dependências não seladasVerifique pelo PowerShell após o firewall ser aberto:
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.
| Item | Por que importa |
|---|---|
global.json fixa o SDK em 7.0.x com rollForward: latestFeature | Impede que máquinas com net8/net9 lado a lado troquem silenciosamente de SDK no meio da demonstração. |
System.Configuration.ConfigurationManager fixado em 7.0.0 | A demonstração net9 canônica usa 8.0.0, que tem como alvo apenas net8 e falha ao restaurar no 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 legado net4x que o .NET 7 aceita em tempo de execução, mas avisa na restauração. O aviso é cosmético; a supressão mantém a saída de compilação limpa durante a demonstração. |
| CLI da Seal v0.3.238 para Windows x64 | Última versão com binário para Windows; totalmente funcional para remediação NuGet. Os binários para Windows foram descontinuados após esta versão, então não sugira uma versão mais recente. |
12.0.2-sp1 é uma substituição drop-in binariamente compatível para 12.0.2.Pacotes usados por esta demonstração:
| Pacote | Versão Vulnerável | Versão Selada | CVE | CVSS |
|---|---|---|---|---|
| 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ÍTICA |
Outros pacotes NuGet selados disponíveis no feed da Seal (não nesta demonstração, listados para referência):
| Pacote | Versão Vulnerável | Versão Selada | CVE | CVSS |
|---|---|---|---|---|
| log4net | 2.0.0 | 2.0.0-sp1 | CVE-2018-1285 | 9.8 CRÍTICA |
| 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 |
Licença MIT — Consulte o arquivo LICENSE para detalhes.