プロンプトインジェクションの対策をどれだけ積んでいても防げない種類の脆弱性が、Microsoft製のプロンプト管理フォーマット Prompty に見つかった。npmパッケージ @prompty/coreGHSA-w28w-gp39-m4p6 で、CVSS 3.1の基本値は最大値の 10.0、2026年7月24日の公表である。テンプレート本文の評価からNode.jsプロセス上の任意コード実行に至る、サーバーサイド・テンプレートインジェクション(SSTI)だ。押さえてほしいのは、これがプロンプトインジェクションとは別の層で起きているという点である。狙われているのはLLMの判断ではなく、プロンプトを組み立てるレンダラの実装そのものだ。

GHSA-w28w-gp39-m4p6の時系列。2026-07-20に修正PR #404がマージされ2.0.0-beta.5がリリース、2026-07-24にアドバイザリがCVSS 10.0で公表された
公表までの時系列。パッチは公表の4日前に入っていた(出典: GHSA-w28w-gp39-m4p6 および microsoft/prompty PR #404 のAPI実測値)
30秒でわかる GHSA-w28w-gp39-m4p6(2026年7月26日時点)
  • 何が起きたか@prompty/core のTypeScript製Nunjucksレンダラが、テンプレート本文のJavaScriptメンバー参照を無制限に評価していた。constructorprototype をたどってホストのNode.jsプロセス上でコードを実行できる。
  • 深刻度:CVSS 3.1 = 10.0AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H)。CWE-94 と CWE-1336。CVE番号は本稿執筆時点で未割当
  • 前提条件つきの10.0:アドバイザリは影響対象を「信頼できない・コミュニティ由来・クローンした・LLMが生成した .prompty をレンダリングしているアプリケーション」と明示している。無条件の事前認証RCEではない。
  • 影響範囲は2系列<= 0.1.4(修正 0.1.5)と >= 2.0.0-alpha.1, <= 2.0.0-beta.4(修正 2.0.0-beta.5)。片方だけ見ると取りこぼす。
  • いま何をするかnpm ls @prompty/core で間接依存まで含めて解決済みバージョンを確認し、上の2系列それぞれの修正版以上へ上げる。あわせて自前のNunjucks/Jinjaレンダラに外部由来の文字列が入る経路を棚卸しする。

この記事は開発者向けのセキュリティ解説です。サプライチェーン全体の攻撃手法と防御ツールの見取り図は サプライチェーンセキュリティ2026|攻撃手法・防御ツール・実践チェックリスト にまとめています。

Prompty(@prompty/core)で何が起きたのか

Promptyは、LLMに渡すプロンプトを .prompty という単一ファイルの資産として扱うためのフォーマットとツール群だ。公式リポジトリの説明では、プロンプトの可観測性・理解しやすさ・可搬性を高めることを目的に掲げている。frontmatter にモデル設定や入力スキーマを書き、本文にテンプレートを書く。この「本文のテンプレート」を実際に文字列へ展開するのがレンダラであり、今回問題になったのはそのうちTypeScript実装のNunjucksレンダラである。

リポジトリの実体を確認しておくと、microsoft/prompty はスター 1,235、fork 120、主要言語はTypeScript、ライセンスは MIT(いずれも2026年7月26日時点のGitHub API実測値)。Microsoft傘下のリポジトリとしては大規模とは言えない規模だが、Prompty形式はAzure AI Foundry系のツールチェーンやVS Code拡張から参照される想定のフォーマットで、パッケージの母数以上に「プロンプトの受け渡し形式」として広がる余地を持っている。そこにCVSS最大値の脆弱性が出たという点が、この件を単なる小規模OSSの不具合と切り離している。

GHSA-w28w-gp39-m4p6の主要数値。CVSS 10.0、パッチが必要な系列は2つ、パッチ先行4日、割当済みCVEは0件
数字で押さえるGHSA-w28w-gp39-m4p6。満点に効いているのはCVSSベクタの Scope:Changed(出典: GitHub Advisory Database の実測値)

CVSS 10.0の内訳と、アドバイザリが明示した前提条件

CVSSベクタは CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H で、基本値は10.0になる。読み方を分解すると、ネットワーク経由(AV:N)・攻撃条件が低い(AC:L)・権限不要(PR:N)・利用者の操作不要(UI:N)で、機密性・完全性・可用性のすべてに高い影響(C:H/I:H/A:H)が出る。そして満点まで押し上げているのが S:C(Scope: Changed) ——脆弱なコンポーネントの管理境界を越えて別のコンポーネントに影響が及ぶ、という評価だ。テンプレートエンジンの内側で始まった評価がホストのNode.jsプロセス全体に届く、という本件の性質がここに反映されている。

ただし数値だけを切り出すと誤読を招く。アドバイザリのImpact欄は影響対象をこう限定している。「信頼できない、コミュニティ由来、クローンした、あるいはLLMが生成した .prompty ファイルをTypeScriptランタイムでレンダリングしているアプリケーション」が、攻撃者の制御下にあるコードをNode.jsホストプロセスの権限で実行させうる、という書き方だ。つまり10.0は「その前提が成り立ったときの最大被害」を表しており、外部から誰でも叩ける事前認証RCEが常時成立するという意味ではない。

数値と前提をセットで読む
CVSS 10.0は「悪用が成立したときにどこまで壊れるか」の指標で、「悪用がどれだけ簡単に成立するか」を単独で示すものではない。本件で問われるのはレンダリング対象のテンプレートがどこから来たかの1点である。自分たちで書いた .prompty しかリポジトリから読んでいない構成は前提から外れる。一方で、テンプレートを設定値・DB・APIレスポンス・ユーザー投稿・LLMの出力から受け取っているなら、前提に当てはまる。

最後の「LLMが生成した」という条件は現実味がある。プロンプトをLLM自身に書かせて .prompty として保存し、それをレンダリングして次の推論に回す——という自己改善ループは実装として珍しくない。この構成では、外部から観測された内容に引きずられたモデル出力が、そのままテンプレート本文として評価されうる。ここでプロンプトインジェクションがSSTIの入口として連結する可能性があり、本件が単独の実装バグに留まらない理由でもある。

なお、本件にはCVE番号が割り当てられていない(アドバイザリの cve_id は空)。CVE番号で社内の脆弱性管理台帳を引いている組織は、この件をGHSA IDとnpmパッケージ名・バージョン範囲で登録する必要がある。報告者はGitHubユーザー lexdotdev としてクレジットされている。

項目 実測値(2026-07-26時点)
アドバイザリID GHSA-w28w-gp39-m4p6
CVE番号 未割当
公表日時 2026-07-24 16:23 UTC
深刻度 Critical / CVSS 3.1 = 10.0
CVSSベクタ AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CWE CWE-94(コードインジェクション)/CWE-1336(テンプレートエンジン)
対象パッケージ npm @prompty/core(TypeScript製Nunjucksレンダラ)
影響バージョン <= 0.1.4>= 2.0.0-alpha.1, <= 2.0.0-beta.4
修正バージョン 0.1.52.0.0-beta.5
修正コミット PR #404(2026-07-20 17:52 UTC マージ・6ファイル +122/-12)
報告者 lexdotdev

仕組み:Nunjucksレンダラのメンバー参照から任意コード実行へ

アドバイザリのSummaryは原因をこう述べている——TypeScript製のNunjucksレンダラが、信頼できない .prompty のテンプレート本文をJavaScriptのメンバーアクセスを制限しないまま評価していた。攻撃者の制御下にあるテンプレートは constructor やプロトタイプのプロパティをたどって、ホストのNode.jsプロセス内でJavaScriptを実行できた。

この経路自体は、JavaScriptのテンプレートエンジンにおける古典的な問題として知られている。任意のオブジェクトから constructor をたどれば関数コンストラクタに到達でき、そこから文字列をコードとして構築する道が開く。テンプレートエンジンは本来「値を安全に文字列へ展開する」ための層であって、言語のオブジェクトグラフを自由に歩ける場所ではない。にもかかわらず、多くのエンジンは利便性のためにメンバー参照を素通しにしている。修正前の実装は、Nunjucks環境を autoescape: false かつ throwOnUndefined: false で構成したうえで、テンプレート文字列をそのまま renderString に渡していた。

攻撃連鎖の流れ。.promptyの取り込みからNunjucksレンダラ、無制限なメンバー参照、Function構築、ホストプロセスでの実行まで
CWE-1336からCWE-94へ連鎖する経路。テンプレート本文の評価がホストプロセスに届く(出典: GHSA-w28w-gp39-m4p6のSummaryとPR #404の差分から構成)
flowchart TD A["外部由来の .prompty 本文
共有・クローン・LLM生成"] --> B["NunjucksRenderer.render()"] B --> C["env.renderString で評価
autoescape: false"] C --> D{"メンバー参照に
制限はあるか?"} D -- "修正前: 制限なし" --> E["constructor / prototype に到達"] E --> F["関数コンストラクタ経由で
コードを構築・実行"] F --> G["Node.js ホストプロセスの権限で動作
Scope: Changed"] D -- "修正後: own-data のみ" --> H["例外を投げてレンダリング中断"]

パッチのテストが示す「何が拒否されるようになったか」

攻撃コードそのものを組み立てて示すことはしないが、修正コミット(047756f)が追加した回帰テストを見れば、どの形が危険と判断されたのかは正確に分かる。テストは以下のテンプレートがいずれも例外になることを確認している。

{{ value.constructor }}     → "Unsafe template member access" で例外
{{ value.__proto__ }}       → 同上
{{ value.prototype }}       → 同上
{{ callback() }}            → "Template function calls are not allowed" で例外

同時に、正常系として {{ customer.name }} のような自前データのネストしたプロパティ参照は通ることもテストされている。つまり修正の方向性は「テンプレートで書けることを削る」であって、「危険な文字列をブラックリストで弾く」ではない。SSTI対策としてはこちらが本筋で、入力側のサニタイズで守ろうとすると回避経路の探索競争になる。

テンプレートエンジンの防御は「入力を洗う」ではなく「評価できる範囲を削る」で行う——パッチの設計がそれを実演している。

プロンプトインジェクションとの違い:狙われるのはモデルではなくレンダラ

ここが本件でいちばん誤解されやすい部分だ。プロンプトインジェクションは、LLMに渡す指示や参照文書に攻撃者の文章を混ぜ込み、モデルの振る舞いを変える攻撃である。被害はモデルの出力、あるいはモデルが呼び出すツールの誤作動として現れる。当サイトでもこれまで、GitHubコメントがAIエージェントを乗っ取る:「Comment and Control」攻撃の仕組みと防御策npmタイポスクワット×プロンプトインジェクション|Sentry偽装でAIエージェントの障害対応を乗っ取る攻撃 のように、エージェント側から見た攻撃面を扱ってきた。

本件はそれとは層が違う。テンプレートがレンダラに渡された時点で決着しており、LLMの推論を一切経由しない。モデルは無関係で、被害はNode.jsプロセスの制御という形で着地する。

4層のうちどこが攻撃されるか。L1の入力層が従来のプロンプトインジェクション、L2のプロンプトテンプレート層が本件、L3のLLMは素通り、L4のホストプロセスに被害が着地する
本件はL2のテンプレートレンダラで完結し、L3のモデル推論を経由しない点が従来型と異なる

この違いは対策の効き方に直結する。プロンプトインジェクション対策として整備されがちな仕掛け——入力のフィルタリング、システムプロンプトの防御的記述、出力の検証、ガードレール用のモデル——は、どれも本件には効かない。テンプレート文字列がレンダラに到達する前に止めるか、レンダラ自身が評価範囲を絞るか、そのどちらかしか防御線がない。

観点 プロンプトインジェクション テンプレートインジェクション(本件)
攻撃対象 LLMの判断・指示の優先順位 テンプレートレンダラの実装
汚染される対象 ユーザー入力・参照文書・ツール出力 テンプレート本文そのもの
モデル推論の関与 必須(モデルが騙される) 不要(モデルに届く前に成立)
成功時の直接的な影響 出力の改変・意図しないツール呼び出し ホストプロセスでの任意コード実行
結果の再現性 確率的(モデル・温度に依存) 決定的(コード実行なので毎回同じ)
有効な対策 入力の分離・権限最小化・出力検証 レンダラの評価範囲の制限・テンプレート出自の管理
CVSSに乗りやすいか 乗りにくい(振る舞いの問題) 乗る(明確な実装欠陥)

表の最下段は運用上の意味がある。プロンプトインジェクションは「モデルが騙された」という確率的な振る舞いの問題なので、CVEやCVSSという枠組みに載せづらい。対してテンプレートインジェクションは実装欠陥として明確に切り出せるため、アドバイザリとして流通し、依存関係スキャナで検出できる。裏を返せば、npm audit や Dependabot が拾ってくれるのはこちら側だけであり、モデル側の攻撃面は依存関係スキャンでは一切見えない。両方を別々に見る必要がある。

対策:2つのバージョン系列とパッチが変えた4点

対策はアップグレードである。ただし影響バージョンが2つの系列に分かれている点に注意が必要で、ここを取り違えると「上げたのに直っていない」が起こる。

系列 影響を受ける範囲 修正版 npmのdist-tag
0.x(安定版) <= 0.1.4 0.1.5 latest
2.x(プレリリース) >= 2.0.0-alpha.1, <= 2.0.0-beta.4 2.0.0-beta.5 alpha

npmレジストリを確認すると、@prompty/core に公開されているバージョンは 0.1.2 / 0.1.3 / 0.1.4 / 2.0.0-alpha.12.0.0-alpha.11 / 2.0.0-beta.12.0.0-beta.5 / 0.1.5 で、1.x系は存在しない。2026年7月26日時点の latest は修正済みの 0.1.5alpha タグは 2.0.0-beta.5 を指している。したがって新規に npm install @prompty/core すれば修正版が入るが、既存プロジェクトのlockfileは当然そのままなので、明示的な更新が必要になる。

「0.1.5以降なら安全」は2.x系には当てはまらない
プレリリース版を追いかけて 2.0.0-beta.3 などを使っている場合、バージョン番号は 0.1.5 より大きいが未修正である。自分がどちらの系列に乗っているかを先に確認し、系列ごとの修正版と比べること。

アップグレード手順は次のとおり。

# 0.x(安定版)を使っている場合
npm install @prompty/core@^0.1.5

# 2.x のプレリリース系を使っている場合
npm install @prompty/[email protected]

# 依存ツリー全体を修正版で解決し直す(間接依存を含む)
npm update @prompty/core && npm ls @prompty/core

パッチが実際に変えた4点

修正はPR #404「fix(typescript): restrict Nunjucks template execution」で入り、2026-07-20 17:52 UTC にマージされた。差分は6ファイル・122行追加/12行削除で、本体の変更は runtime/typescript/packages/core/src/renderers/nunjucks.ts に集中している。中身を読むと、防御は4つの独立した制限として実装されている。

PR #404が追加した4つの制限。危険プロパティの拒否、自前データのみ返す、テンプレ内関数呼び出しの全面禁止、入力をprototype無しに複製
パッチは「実行できる範囲」を削って直した(出典: commit 047756f の nunjucks.ts 差分)

危険プロパティ名の明示的な拒否__proto__ / constructor / prototype を集合として持ち、テンプレートからこれらを参照したら例外を投げる
自前データのみを返すメンバー参照Object.getOwnPropertyDescriptor を使い、対象オブジェクト自身が持つデータプロパティの値だけを返す。プロトタイプチェーンをたどらず、getter経由の値も返さない
テンプレート内の関数呼び出しを全面禁止:Nunjucksランタイムの呼び出しラッパーを差し替え、テンプレートから関数を呼ぼうとした時点で例外にする。呼び出し対象の関数は実行されない(テストで確認されている)
レンダリング入力の再構築:入力オブジェクトを再帰的に走査し、プロトタイプを持たないオブジェクトへ値だけを複製する。循環参照は WeakMap で検出して無限再帰を避ける

実装として興味深いのは、これらがNunjucksの内部ランタイム関数(メンバー参照と関数呼び出しのラッパー)をレンダリング中だけ差し替え、finally で必ず元に戻す形で入っている点だ。ライブラリ側にフックがない制約のもとで、影響範囲をレンダリング呼び出しの内側に閉じ込めている。アドバイザリのRemediation欄も、修正後のレンダラは「レンダリング入力を自前データのみの値へ整え、constructor/prototypeのメンバー参照を拒否し、テンプレート関数呼び出しを許可しない」一方で「通常の変数展開・条件分岐・繰り返し・自前のネストしたデータプロパティは引き続きサポートされる」と述べており、コードの実装と一致している。

読者の3つの問いへの答え
何が起きたか:プロンプトテンプレートを展開するレンダラの実装欠陥で、テンプレート本文からホストのNode.jsプロセス上のコード実行に至った(CVSS 10.0・ただし外部由来テンプレートを読む構成が前提)。
何を確認すればいいかnpm ls @prompty/core で解決済みバージョンを2系列それぞれの修正版と比較し、あわせて自前のNunjucks/Jinjaレンダラへ外部由来の文字列が入る経路を棚卸しする。
何が代わりの防御になるか:入力のサニタイズではなく「テンプレートで評価できる範囲の制限」。パッチと同じ考え方を自前のレンダラにも適用する。

自環境の確認手順|プロンプトインジェクション対策とは別に棚卸しすべき箇所

ここからは自分の環境で実行する確認手順である。2段構えで見る。@prompty/core が入っているか②自前のテンプレートレンダラに同種の穴がないか。②を省くと、今回のアドバイザリは片付いても同じ構造の欠陥が自社コードに残る。

① @prompty/core の解決済みバージョンを確認する

直接依存としてpackage.jsonに書いていなくても、他のパッケージ経由で入っていることがある。宣言ではなく実際に解決されたバージョンを見るのが要点だ。

# 直接・間接を問わず、解決済みバージョンをツリーで確認する
npm ls @prompty/core

# lockfile から実際に固定されているバージョンを拾う(npm 以外でも確認したい場合)
grep -A3 '"@prompty/core"' package-lock.json | grep '"version"'

# pnpm / yarn の場合はこちら(なぜ入っているかも分かる)
pnpm why @prompty/core
yarn why @prompty/core

出力の読み方は次の表のとおり。系列を先に判定してから修正版と比較する。

npm ls の出力 判定 対応
@prompty/[email protected] 以下 影響あり 0.1.5 以上へ更新
@prompty/[email protected] 修正済み 対応不要
@prompty/[email protected].* 影響あり 2.0.0-beta.5 へ更新
@prompty/[email protected]beta.4 影響あり 2.0.0-beta.5 へ更新
@prompty/[email protected] 修正済み 対応不要
(empty) / 該当なし 依存していない ②へ進む

なお @prompty/anthropic@prompty/openai などのプロバイダ別パッケージは @prompty/core に依存している。自分のpackage.jsonに @prompty/core を直接書いていなくても、これらを入れていれば間接的に引き込まれる。自分のpackage.jsonを読むのではなく npm ls を実行するのは、この間接依存を取りこぼさないためだ。

② 自前のテンプレートレンダラを棚卸しする

今回と同じ構造の欠陥は、テンプレートエンジンを直接使っている自社コードにも起こりうる。特に、LLM向けのプロンプトを組み立てる箇所は「テンプレートに外部由来の文字列を渡す」設計になりやすい。次のコマンドで候補を洗い出す。

# .prompty ファイルの棚卸し(どこから来たファイルかを1件ずつ確認する)
find . -name '*.prompty' -not -path './node_modules/*'

# テンプレート文字列を動的に評価している箇所を洗う(JS/TS と Python)
grep -rn "renderString\|nunjucks.Environment\|compile(" \
  --include=*.ts --include=*.js . | grep -v node_modules

# Python 側:Jinja2 で文字列からテンプレートを作っている箇所
grep -rn "from_string\|Template(" --include=*.py . | grep -v -e '\.venv' -e site-packages

ヒットした箇所ごとに、次の3点を確認する。

テンプレート本文の出自:リポジトリ内の固定ファイルか、それとも設定値・DB・APIレスポンス・ユーザー投稿・LLM出力から来ているか。後者なら本件と同じ前提が成立している
サンドボックスの有無:Jinja2なら SandboxedEnvironment を使っているか(素の Environment は属性アクセスを制限しない)。Nunjucksには同等の標準サンドボックスがないため、今回のパッチのようにメンバー参照と関数呼び出しを自前で絞る必要がある
渡している値の素性:テンプレートのコンテキストに、メソッドやクラスインスタンスをそのまま入れていないか。データだけを渡す設計であれば、攻撃者がたどれるオブジェクトグラフはそもそも狭い

「テンプレートはデータを受け取り文字列を返す」——この境界を守れているかが、SSTIに強い設計かどうかの分かれ目になる。

依存関係スキャナの観点も補っておくと、npm audit やDependabotはGHSAデータベースを参照するため、公表済みの本件は自動で検出できる。一方で②の自前レンダラの穴はどのスキャナも検出しない。前者は仕組みに任せ、後者は人が読むしかない、という分担になる。

影響範囲:2026年7月に集中したテンプレートインジェクション公表

最後に、この件を単発の事故として見るか、傾向の一部として見るかを整理したい。GitHub Advisory DatabaseのAPIで、2026年7月1日から25日までに公表されたアドバイザリをテンプレート/式インジェクション系のCWE(CWE-1336・CWE-94・CWE-917)で横断検索すると、同種の欠陥がこの期間に固まって公表されていることが分かる。

2026年7月のテンプレートインジェクション系アドバイザリのCVSS比較。@prompty/coreが10.0で最高値、Mautic 9.9、velocityjs 9.8、beetl 9.8、Formie 9.8、oh-my-posh 7.8、GeoNetwork 7.1、Gitleaks 6.3
同期間のテンプレート/式インジェクション系アドバイザリ。8件中7件は非AI系のソフトウェア(出典: GitHub Advisory Database API の実測値)
公表日 対象 エコシステム CVSS 3.1 概要
07-24 @prompty/core npm 10.0 Nunjucksレンダラの SSTI → RCE(本件)
07-24 velocityjs npm 9.8 プロパティ読み取りから関数コンストラクタ経由でRCE
07-24 oh-my-posh go 7.8 パスセグメントのテンプレートインジェクションで任意コマンド実行
07-23 beetl Java 9.8 式言語インジェクション(CWE-917)
07-21 Gitleaks(CVE-2026-63728) go 6.3 テンプレートインジェクション
07-09 YesWiki(CVE-2026-52762) composer 未登録 認証済み管理者によるSSTI → RCE
07-06 Formie(CVE-2026-52889) composer 9.8 隠しフィールドの既定値経由のSSTI
07-02 Mautic(CVE-2026-9558) composer 9.9 テーマテンプレートのSSTI
07-01 GeoNetwork(CVE-2026-39379) maven 7.1 クライアントサイドのテンプレートインジェクションによる反射型XSS

この並びから読み取れることを、データが支えている範囲で正直に書く。この波の大半はAIと無関係のソフトウェアである。 CMS(Mautic)、Wiki(YesWiki)、フォームビルダー(Formie)、シェルプロンプト(oh-my-posh)、シークレットスキャナ(Gitleaks)、Javaのテンプレートエンジン(beetl)、地理情報カタログ(GeoNetwork)——上の9件のうちAI関連と言えるのは @prompty/core と、同じ7月24日に公表されたMicrosoft Kiotaの事例(OpenAPI拡張フィールド経由のコマンドインジェクション。Copilotプラグイン生成に関わる)の2件だけだ。

したがって「AIのテンプレート層が新しい攻撃面になった」という総括は、この実測データからは言えない。より正確なのは逆向きの整理になる——テンプレートエンジン層のSSTI→RCEは以前から広く存在する定番の欠陥類型であり、2026年7月にその公表が集中し、その波がプロンプトテンプレート層にも到達したvelocityjs の事例が「プロパティ読み取りから関数コンストラクタへ」という本件とまったく同じ技法の系統で、しかも同じ日にnpmで公表されている事実は、この読み方を裏づけている。

新しいのは攻撃技法ではなく、その技法が届く先にプロンプトテンプレートが加わったことである。

この整理には実務上の含意がある。プロンプトを扱う層を「AIの新領域」として特別扱いするのではなく、テンプレートエンジンを使う既存のコードと同じ検査項目を当てればよい、ということだ。SSTIの検査は20年近く積み上げられてきた領域で、着眼点は確立している。テンプレートの出自を管理し、サンドボックス化されたエンジンを使い、コンテキストにはデータだけを渡す。.prompty だからといって新しい作法が必要になるわけではない。

まとめ

GHSA-w28w-gp39-m4p6 の要点
・`@prompty/core` のTypeScript製Nunjucksレンダラが、テンプレート本文のメンバー参照を無制限に評価しており、`constructor` 経由でホストのNode.jsプロセス上のコード実行に至った。CVSS 3.1は最大値の10.0(`S:C` が効いている)
・ただしアドバイザリ自身が前提を明示している。危険なのは「信頼できない・コミュニティ由来・クローンした・LLMが生成した」`.prompty` をレンダリングしている構成で、無条件の事前認証RCEではない
・影響は2系列に分かれる。`<= 0.1.4`(修正 `0.1.5`)と `>= 2.0.0-alpha.1, <= 2.0.0-beta.4`(修正 `2.0.0-beta.5`)。バージョン番号の大小だけで判断せず、系列を先に見る
・パッチは危険プロパティの拒否・自前データのみのメンバー参照・テンプレート内関数呼び出しの全面禁止・入力の再構築という4点で、「評価できる範囲を削る」方向で直している。入力のブラックリストではない
・確認は `npm ls @prompty/core` で間接依存まで含めた解決済みバージョンを見ることから。あわせて自前のNunjucks/Jinjaレンダラへ外部由来の文字列が入る経路を棚卸しする
・同期間のGHSAを横断すると、テンプレート/式インジェクションの公表は7月に集中しており、その大半は非AI系ソフトウェアだった。新しいのは技法ではなく、その技法が届く先にプロンプトテンプレートが加わったこと

プロンプトを「資産」として扱う流れは、可観測性や再利用性の観点では明確な前進だ。ただし資産化はファイル化を意味し、ファイル化は共有・クローン・生成を意味する。テンプレートが外から入ってくる経路ができた時点で、それはテンプレートエンジンのセキュリティ問題の射程に入る。CVE番号がまだ振られていないこの1件は、その入口を示す最初の目立った事例として記録しておく価値がある。

参照ソース

GHSA-w28w-gp39-m4p6 — Prompty: Server-Side Template Injection to Remote Code Execution in the @prompty/core Nunjucks Renderer — CVSSベクタ・CWE・影響/修正バージョン・Impact欄の前提条件・報告者クレジット
microsoft/prompty PR #404 — fix(typescript): restrict Nunjucks template execution — マージ日時(2026-07-20 17:52 UTC)・変更規模(6ファイル +122/-12)・修正方針
microsoft/prompty commit 047756fnunjucks.ts の実際の差分と追加された回帰テスト(拒否されるテンプレート形)
microsoft/prompty(公式リポジトリ) — スター1,235・fork 120・MIT・TypeScript(2026-07-26 GitHub API実測)
GitHub Advisory Database — 2026年7月1〜25日のCWE-1336/CWE-94/CWE-917横断検索による同種アドバイザリの一覧とCVSS実測値