これは、標準的な seal-security-nuget-demo(net9.0 をターゲットにしている)を再ターゲットしたフォークです。エクスプロイトのストーリー、コントローラー、シールドパッケージのリストは同一です — TargetFramework のみが異なります。
これが存在する理由は、ほとんどのエンタープライズ顧客が要求に応じて最新の .NET SDK に移行できないためです。.NET 7 は 2024 年 5 月 14 日にサポート終了に達しましたが、実際の本番環境では、互換性、認定、または運用上の理由から、依然として .NET 7 で稼働しています。これはまさに Seal Security が設計されたケースです。顧客がメジャーバージョンアップグレードを実行できない(または実行しない)場合、Seal は脆弱な依存関係を同じバージョンのままその場でパッチし、公開 API の変更も顧客アプリのコード編集も行いません。このデモにより、顧客に net8/net9 を先にインストールしてもらう代わりに、顧客の実際のスタック上でこの会話ができるようになります。
このフォークは global.json で SDK を 7.0.x に固定しているため、デモ中に誤ってアップグレードが紛れ込むことはありません。
このデモアプリケーションは、Newtonsoft.Json 12.0.2 を使用してユーザー入力を設定オブジェクトとして解析する、シンプルな ASP.NET Core ウェルカムページです。アプリには名前フィールドがあり、名前を入力して Go をクリックすると、 と表示されます。内部では、入力を Newtonsoft.Json の に渡します。それだけです — 一般的な JSON ライブラリの完全に標準的な使用方法です。
JsonConvert.DeserializeObject<NestedConfig>()問題は、Newtonsoft.Json 12.0.2(および 13.0.1 より前のバージョン)に CVE-2024-21907 — CVSS スコア 7.5(HIGH) の高深刻度サービス拒否(DoS)脆弱性があることです。このデモは、Seal Security がメジャーバージョンアップグレードを必要とせずに脆弱性をその場でパッチする方法を示しています。
Newtonsoft.Json の JsonConvert.DeserializeObject<T>() メソッドは、深くネストされた JSON ペイロードを作成することで悪用される可能性があります。型付きオブジェクト(POCO)への逆シリアル化時、ライブラリの JsonSerializerInternalReader は真に再帰的な呼び出し(CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue → CreateValueInternal)を実行し、スタックオーバーフローを引き起こして、アプリケーションのクラッシュ(サービス拒否)につながります。
アプリはユーザー入力を受け取り、Newtonsoft.Json を通じて解析します。入力が URL の場合、アプリは最初にコンテンツを取得します — これは設定ローダー、API テスター、Webhook レシーバーで使用される現実的なパターンです:
public class NestedConfig
{
[JsonProperty("n")]
public NestedConfig? N { get; set; }
}
var config = JsonConvert.DeserializeObject<NestedConfig>(name);
通常の入力: alice と入力 → 「Welcome, alice!」と表示
エクスプロイト: この URL を名前フィールドに貼り付けて、Go をクリック:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
アプリは URL であることを検出し、json-payload(深くネストされた JSON {"n":{"n":{...}}})を取得し、Newtonsoft.Json を通じて再帰的な NestedConfig クラスに逆シリアル化します — スタックオーバーフローを引き起こします。
JsonSerializerInternalReader は、すべてのネストレベルで CreateValueInternal → CreateObject → PopulateObject → SetPropertyValue を再帰します。約 5,000 レベルの深さで、スレッドスタックを使い果たし、アプリケーションは StackOverflowException でクラッシュします — プロセスは即座に停止します(グレースフルなエラーハンドリングは不可能)。
この脆弱性により、攻撃者は以下を行うことができます:
公開されている修正にはバージョン 13.0.1 へのアップグレードが必要です。ただし、メジャーバージョンのアップグレードには、しばしば以下の問題が伴います:
このため、「単にアップグレードする」修正は、開発者の時間を数週間簡単に消費するプロジェクトになり得ます — その間、脆弱性は放置されたままになります。
Seal のパッチ版(12.0.2-sp1)は、公開 API を変更せずに再帰深度保護を追加します。パッチは:
MaxDepth 制限を追加これは Newtonsoft.Json 13.0.1 で適用されたものと同じ緩和戦略であり、ドロップイン置換として 12.0.2 にバックポートされたものです。
このデモには、Seal Security がパッチできる他の脆弱な NuGet パッケージも含まれています:
log4net の XML 設定解析におけるXML 外部エンティティ(XXE)脆弱性。log4net 設定ファイルを制御できる攻撃者は、以下を行うことができます:
System.Net.Httpに関する注記: 標準の net9 デモには、CVE-2017-0249 用の脆弱なSystem.Net.Http 4.3.0参照も含まれています。この net7 フォークでは省略しています。これは、.NET 7 ではSystem.Net.Httpが BCL の一部であり、スタンドアロンのパッケージ参照は痕跡的なメタパッケージであるためです —dotnet add package --source <local-nupkg>で既知のエッジケースがあり、これはまさに Seal CLI がシールドバージョンを適用する方法です。これを削除することで、デモのストーリーを変更せずにseal fixステップを確実に実行できます(HttpClientは引き続き正常に動作します。ランタイムが提供します)。
Windows CLI バイナリは v0.3.238 以降で廃止されました。v0.3.238 は Windows での NuGet 修復に完全に対応しています。
詳細な Windows Server インストール + 実行ガイドは README-WINDOWS-SERVER.md にあります。以下のクイックスタートは同じ手順を簡潔にまとめたものです。
PowerShell:
$env:SEAL_TOKEN = "your-seal-token-here"
$env:SEAL_PROJECT = "nuget-demo-net7"
cd seal-security-nuget-demo-net7
# 復元(nuget.org と Seal フィードから取得 — nuget.config を参照)
dotnet restore
# ビルドと実行
dotnet build
dotnet run
http://localhost:5000 を開きます — アプリは脆弱な依存関係で実行されています。
名前フィールドに alice と入力し、Go をクリックします。「Welcome, alice!」 と表示されるはずです。
次の URL を名前フィールドに貼り付けて、Go をクリックします:
https://raw.githubusercontent.com/seal-sec-demo-2/json-payload/main/payload.json
パッチ未適用の結果: ブラウザにエラー / 接続リセットが表示されます — アプリは JsonSerializerInternalReader.CreateValueInternal で StackOverflowException によりクラッシュしました。プロセスは停止しています。
# (任意 — 上記で既に実行済み)最初に依存関係を復元
dotnet restore
# Seal CLI を実行して脆弱性を修正
seal fix . --mode remote -v
# シールドバージョンを取得するために再度復元
dotnet restore
# パッチ適用済みアプリのビルドと実行
dotnet build
dotnet run
アプリは現在、パッチ適用済みバージョン(Newtonsoft.Json 12.0.2-sp1、log4net 2.0.5-sp1)を使用しています。
パッチ適用後の結果: 同じエクスプロイト URL を貼り付けます → ページに 「Blocked by Seal patch: MaxDepth of 64 has been exceeded.」 と表示されます — Newtonsoft.Json のパッチ適用済み再帰制限が深いペイロードを拒否しました。サーバーは正常に動作し続けます。
dotnet list package
Seal Security パッチを示す -sp1 サフィックスが付いたパッケージが表示されるはずです。
CLI ステップは、依存関係のインストール直後、最終ビルドの前に追加する必要があります。
# 1. 依存関係の復元
dotnet restore
# 2. <--- ここで Seal CLI を実行
$env:SEAL_TOKEN = "your-seal-token-here"
$env:SEAL_PROJECT = "nuget-demo-net7"
seal fix . --mode remote -v
# 3. 再度復元(シールドバージョンを取得するため)
dotnet restore
# 4. ビルド
dotnet build
| モード | 説明 |
|---|---|
all | 利用可能なすべての修正を自動的に適用 |
remote | Seal UI で承認された修正のみを適用 |
local | .seal-actions.yml で定義された修正のみを適用 |
このリポジトリの .seal-actions.yml には、local モード用の 3 つのシールドオーバーライドが既にリストされているため、seal fix . --mode local -v はオフラインで動作します(アーティファクトサーバーにはトークンが依然として必要です)。
nuget.config は、環境変数を使用して Seal Security を使用するように事前設定されています:
<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>
| 変数 | 説明 |
|---|---|
SEAL_TOKEN | Seal Security アクセストークン |
SEAL_PROJECT | プロジェクト ID(例: nuget-demo-net7) |
Seal CLI は、以下の宛先への送信 HTTPS(TCP 443)が必要です:
cli.sealsecurity.io — スキャン / 修正設定authorization.sealsecurity.io — トークン検証nuget.sealsecurity.io — シールド .nupkg のダウンロードd2zko6i8myndc4.cloudfront.net — 実際のシールドアーティファクトを提供する CDN(.sealsecurity.io ホスト名はここにリダイレクトされます)api.nuget.org / 標準の nuget.org エンドポイント — シールドされていない依存関係用ファイアウォールを開いた後、PowerShell から確認します:
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
すべて TcpTestSucceeded: True と報告されるはずです。
| 項目 | 重要な理由 |
|---|---|
global.json が SDK を 7.0.x に rollForward: latestFeature で固定 | net8/net9 がサイドバイサイドでインストールされたマシンが、デモ中に SDK を静かに切り替えるのを防ぎます。 |
System.Configuration.ConfigurationManager が 7.0.0 に固定 | 標準の net9 デモは 8.0.0 を使用していますが、これは net8 のみをターゲットとしており、net7 では復元に失敗します。7.0.0 は log4net が必要とする同じ API サーフェスを持っています。 |
csproj で NU1701 が抑制 | log4net 2.0.5 はレガシーな net4x TFM を宣伝しており、.NET 7 は実行時には受け入れますが、復元時に警告します。この警告は外観上のものであり、抑制によりデモ中のビルド出力がクリーンに保たれます。 |
| Windows x64 用 Seal CLI v0.3.238 | Windows バイナリが付属する最後のリリース。NuGet 修復に完全に対応しています。Windows バイナリはこのバージョン以降で廃止されたため、新しいリリースを提案しないでください。 |
12.0.2-sp1 は 12.0.2 のバイナリ互換のドロップインです。このデモで使用されるパッケージ:
| パッケージ | 脆弱なバージョン | シールドバージョン | CVE | CVSS |
|---|---|---|---|---|
| Newtonsoft.Json | 12.0.2 | 12.0.2-sp1 | CVE-2024-21907 | 7.5 HIGH |
| log4net | 2.0.5 | 2.0.5-sp1 | CVE-2018-1285 | 9.8 CRITICAL |
Seal フィードから利用可能な他のシールド NuGet パッケージ(このデモには含まれていません。参考用にリストされています):
| パッケージ | 脆弱なバージョン | シールドバージョン | CVE | CVSS |
|---|---|---|---|---|
| log4net | 2.0.0 | 2.0.0-sp1 | CVE-2018-1285 | 9.8 CRITICAL |
| System.Net.Http | 4.3.0 | 4.3.0-sp1 | CVE-2017-0249 | 7.3 HIGH |
| Snappier | 1.1.0 | 1.1.0-sp1 | CVE-2023-28638 | 7.0 HIGH |
| jQuery.Validation | 1.17.0 | 1.17.0-sp1 | CVE-2021-21252 | 7.5 HIGH |
MIT ライセンス - 詳細は LICENSE ファイルを参照してください。