署名を検証しないJWT — SharePoint CVE-2026-55040 が積み上げた4つの欠陥

「JWT を使っているから安全」という言い方は、実は何も言っていない。JWT は署名の入れ物であって、署名を検証することは別の実装が担うからだ。

Microsoft SharePoint の CVE-2026-55040 は、その分離がそのまま脆弱性になった例である。CISA の KEV(既知の悪用された脆弱性カタログ)に 2026-08-18 に収載され、是正期限は 2026-08-21。NVD の参考文献には Exploit タグ付きの公開検証コードが載っている。つまり、再現に高度な解析はもう要らない。

この記事では、Rapid7 が公開した技術解析をもとに「なぜ通ってしまうのか」を4段階で追い、最後に自分の環境が該当するかを判定する手順を置く。

まず切り分ける — Online か オンプレミスか

NVD の CPE に含まれるのは次の3つである。

製品 該当バージョン
SharePoint Server Subscription Edition 16.0.19725.20434 未満
SharePoint Server 2019 該当
SharePoint Server 2016 Enterprise 該当

SharePoint Online(Microsoft 365)は CPE に含まれていない。 Microsoft 365 の SharePoint だけを使っている組織は対象外である。対象になるのは自社サーバで動かしている SharePoint Server で、社内ポータル・ファイル共有・ワークフローの土台として何年も動き続け、更新が止まりがちな種類の資産だ。

棚卸しのときは「SharePoint」という製品名で探すより、社内ポータルの URL からその背後のサーバを辿るほうが確実である。

CVSS は Microsoft(secure@microsoft.com)が CVSS 3.1 で 9.1 CriticalAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N)を付けている。本稿執筆時点で NVD の Primary スコアは未付与。ベクタの配分に注目したい。機密性と完全性が High、可用性が None である。落ちる種類の欠陥ではなく、読まれる・書き換えられる種類の欠陥だ。

何が破られるのか

SharePoint のサービス間(S2S)認証は、入れ子になった JWT を使う。

  • 外側のトークン … 利用者の identity クレームを持つ
  • 内側の「actor token」 … actortoken クレームに埋め込まれ、呼び出し元アプリケーションを表す。信頼された証明書で署名されている想定

検証の流れは SPApplicationAuthenticationModuleV2.TryExtractAndValidateToken() から始まり、Authorization ヘッダの Bearer トークンを取り出し、SPJsonWebSecurityBaseTokenHandlerV2.ReadToken() で解析し、SPJsonWebSecurityTokenHandlerV2.ValidateToken() で検証する。

破綻はこのパイプラインの4か所にある。1つでも塞がっていれば成立しないが、4つとも空いていた。

弱点1: 外側のトークンで署名を要求していない

ValidateToken()TokenValidationParameters を組み立てるとき、次の1行がある。

1
val.RequireSignedTokens = false;

Microsoft.IdentityModel の JWT ライブラリは、このフラグが false だと alg: none のトークンを受け入れる。外側のトークンには署名がまったく要らなくなる。ライブラリは JWT を解析してクレームを埋めるが、暗号的な検証は一切行わない。

同じ場所で val.ValidateAudience = false;val.ValidateIssuer = false; も設定されている。ライブラリ側の検証を軒並み切って、自前の検証に寄せた設計だったと読める。問題は、その自前の検証が以降で埋め合わせになっていないことだ。

弱点2: actor token の署名鍵は解決するが、照合しない

内側の actor token については、x5t ヘッダ(証明書のサムプリント)から署名鍵を解決する処理がある。解決先の候補には SharePoint 自身の STS 署名証明書LocalLoginProvider)が含まれる。

そしてこの証明書の x509 は、未認証で叩ける /_layouts/15/metadata/json/1 エンドポイントから取得できる。

つまり攻撃者は、公開されているエンドポイントから証明書を取り、そのサムプリントを偽造トークンの x5t に書けば、鍵の解決に成功する。

ここまでは「鍵を見つけた」だけである。致命的なのはこの先で、解決した鍵に対して署名を照合する処理がどこにも無い。 コードは x5t から鍵を解決し、SigningToken プロパティを埋め、そこで終わる。Rapid7 の検証では、署名の位置に文字列 AAAA を置いた偽造トークンが通っている。

弱点3: 未登録の証明書を「未登録だから」受け入れる

SigningToken が埋まった状態で ValidateIssuer(token) が呼ばれると、次の分岐に入る。

1
2
3
4
5
6
if (token.ActorToken != null && ((JwtSecurityToken)token.ActorToken).SigningToken != null)
{
ValidateIssuer(((JwtSecurityToken)token.ActorToken).SigningToken as X509SecurityToken,
((JwtSecurityToken)token.ActorToken).Issuer);
return;
}

呼び先の ValidateIssuer(X509SecurityToken, string) は、こう書かれている。

1
2
3
4
5
6
7
8
9
SPTrustedSecurityTokenService providerBySigningCertificate =
SPSecurityTokenServiceManager.LocalOrThrow.TrustedSecurityTokenServices
.GetProviderBySigningCertificate(signingKey.Certificate, tokenIssuer);

if (null == providerBySigningCertificate)
{
// 「この署名証明書に一致する登録済み STS が無いので Issuer を受け入れた」
return; // ← 受理
}

TrustedSecurityTokenServices は登録済みの信頼された STS の集合である。ところが SharePoint 自身のローカル STS 署名証明書は LocalLoginProvider に属していて、この集合には入っていない。したがって GetProviderBySigningCertificatenull を返す。

そして null のとき、このメソッドは例外を投げずに無条件で受理して戻る

設計意図としては「明示的に登録されていない証明書からのトークンも受け入れる」だったのだろう。しかし効果は逆で、攻撃者が SharePoint 自身の証明書を参照すると、それが「未登録」であるがゆえに検証を素通りする。「知らない鍵は拒否する」ではなく「知らない鍵は許可する」になっている、フェイルオープンの典型例である。

弱点4: 最後の署名チェックが「空でないこと」しか見ない

セッショントークンを組み立てる段階で GetTokenSignature が呼ばれる。名前に反して、このメソッドがやっているのは署名文字列が空でないかの確認だけだ。

1
2
3
4
5
string text = ((JwtSecurityToken)jwtToken).RawSignature;
if (string.IsNullOrWhiteSpace(text))
{
text = rawData.Substring(rawData.LastIndexOf('.') + 1);
}

暗号的な検証は行われない。弱点2で置いた AAAA は、ここも「空ではない」ので通過する。

4つ並べると構造が見える。署名を要求しない → 鍵を解決するが照合しない → 未登録なら受理する → 最後は非空チェックだけ。 どの段でも「検証したつもり」のコードは存在するのに、実際に暗号的な照合を行う段が1つも無い。

自分の環境が該当するか判定する

判定は2つの軸で行う。ビルド番号露出である。

ビルド番号

SharePoint 管理シェルで確認する。

1
Get-SPFarm | Select-Object -ExpandProperty BuildVersion

Subscription Edition なら、この値が 16.0.19725.20434 以上であることを確認する。2016 Enterprise と 2019 については、MSRC のアドバイザリ(CVE-2026-55040 のページ)が案内する更新プログラムを適用する。

ビルド番号の比較は目視だと桁を読み違えるので、判定まで機械にやらせるほうがよい。

1
2
3
4
5
6
7
$build = (Get-SPFarm).BuildVersion
$fixed = [Version]"16.0.19725.20434"
if ($build -lt $fixed) {
Write-Output "VULNERABLE: $build (fixed: $fixed)"
} else {
Write-Output "OK: $build"
}

露出

弱点2で使われる /_layouts/15/metadata/json/1未認証で応答する。ここに外から到達できるかどうかは、そのまま「攻撃の初手が外から踏めるか」である。

1
2
curl -s -o /dev/null -w "%{http_code}\n" \
"https://sharepoint.example.internal/_layouts/15/metadata/json/1"

200 が返るなら、その経路からは証明書を取得できる。このエンドポイントを塞ぐことは対策ではない(認証バイパス自体は残るし、社内からの攻撃には効かない)が、更新完了までの猶予をどう見積もるかの材料にはなる。

自分が管理していないホストに対して実行しないこと。上のコマンドは、自組織の資産に対する確認としてのみ使う。

更新以外に効く手が無い

この欠陥の性質を1行でまとめると、「落ちないので、運用側の異常として現れない」である。可用性への影響が None であることは、攻撃を受けても監視のグラフが動かないことを意味する。ログの異常検知で気づくのは難しい。

暫定の緩和として挙げられるのは、SharePoint をインターネットから直接到達できない位置(リバースプロキシや VPN の内側)に置くことだが、社内からの攻撃には効かない。そして認証バイパスである以上、SharePoint 側で認証を強めても回避される。

したがって、確実な対応は更新だけである。KEV の是正期限が 2026-08-21 と短いので、計画は日単位で立てる。

更新前にインターネットへ露出していた SharePoint は、侵害を前提に点検する。見るべきなのは次の4つだ。

  1. コンテンツデータベースに対する想定外の読み取り
  2. サイトコレクション管理者の追加
  3. カスタムソリューション(WSP)や .aspx の追加
  4. SharePoint のサービスアカウントが Active Directory に対して行った操作

4つ目が最も重い。SharePoint のサービスアカウントはドメイン内で強い権限を持っていることが多く、SharePoint 単体の被害では済まないことが多い。完了条件は、(1)全オンプレミス SharePoint が修正ビルドであること、(2)露出していた期間の点検が済んでいること、(3)サービスアカウントとファーム管理者アカウントの資格情報を再発行済みであることの3点になる。

設計として持ち帰るもの

この CVE から取り出せる教訓は、SharePoint に固有ではない。

フェイルオープンの検証は、検証していないのと同じである。 弱点3の if (null == provider) return; は、「一致する登録が見つからなかった」という判断できない状態を「合格」に倒している。判断できない状態を合格に倒す検証は、判断できる状態を作れる攻撃者にとっては存在しないのと同じだ。自分のコードで null や空配列や例外を「とりあえず通す」側に倒している箇所は、同じ形をしていないか確認する価値がある。

そして、検証の段が複数あることは安全の根拠にならない。 この事例では検証らしきコードが4段あった。4段あることが安心の材料になっていたとしたら、それは「どの段が実際に暗号的な照合を行っているか」を誰も追っていなかったということでもある。段の数ではなく、責任を持つ段が1つ以上あるかを確認する必要がある。

掲載中の CVE の対応状況(AWS / GCP / Azure / Linux 別)は CVE Watch にまとめている。

出典

  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-55040(vulnStatus: Analyzed、CVSS 3.1 9.1 Critical / Secondary: secure@microsoft.com、CWE-1390)
  • CISA KEV: 収載 2026-08-18 / 是正期限 2026-08-21 / ランサムウェア利用 Unknown
  • Rapid7: Microsoft SharePoint JWT Token Authentication Bypass Technical Analysis (CVE-2026-55040)
  • MSRC: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-55040

(確認日 2026-08-19。バージョン・KEV の状態は変動するため、最新は一次情報で確認してください。)


署名を検証しないJWT — SharePoint CVE-2026-55040 が積み上げた4つの欠陥
https://blog.hashito.biz/2026/08/19/sharepoint-cve-2026-55040-jwt-validation-chain/
著者
hashito
作成日
2026年8月19日
著作権