目次(5)

Raspberry Pi などで動かす船舶向けデータサーバー Signal K Server(npm: signalk-server)で、リソース API とアプリケーションデータ API のパス・トラバーサルにより、設定ディレクトリの JSON ファイルを読み書き・削除できてしまう不具合(GHSA-4xm8-rg9h-jhq2)が公開されました。security.json に平文で保存されていた JWT の署名鍵が読み出され、管理者トークンの偽造とコマンド実行につながります。GitHub の深刻度は Critical、CVSS v3.1 は 9.8 です。修正版は 2.34.0(10/18 UTC に公開)です。この勧告には CVE 番号が付いておらず、NVD・EPSS・CISA KEV の CVE での照合はできません。
何が起きるか
- v2 の REST リソース API
GET /signalk/v2/api/resources/:resourceType/:resourceIdは、resourceIdを検証せずに保存先のパスへ連結していました。%2Fでエンコードした..を重ねると、保存先の外にある任意の JSON ファイルを読み出せます(勧告の記載)。書き込み・削除も同じ経路で可能とされています。 - JWT の署名鍵は設定ディレクトリの
security.jsonに平文で入っていました。ここが読まれると、利用者のパスワードハッシュと署名鍵が漏れます。 - 署名鍵があれば、管理者の JWT を偽造できます。管理者は
Execute型のプロバイダーを追加でき、作成時にsh -cでコマンドが実行されます。プロバイダーは設定に保存され、再起動後も再実行されます(勧告の説明と手順)。 - 認証の条件:
allow_readonly=true(UI で切り替えられる、匿名での読み取りを許す設定)なら認証なしで成立します。既定(allow_readonly=false)では匿名は 401 になりますが、読み取り専用の利用者のトークンがあれば成立します。
影響を受ける条件
| 項目 | 内容 |
|---|---|
| 対象 | signalk-server 2.0.0 以上 2.34.0 未満、@signalk/resources-provider 1.0.0 以上 1.5.3 未満 |
| 修正版 | signalk-server 2.34.0、@signalk/resources-provider 1.5.3(いずれも npm で 10/18 UTC 公開) |
| 弱点 | CWE-22(パス・トラバーサル) |
| 評価 | GitHub 提供の CVSS v3.1 は 9.8(AV:N/AC:L/PR:N/UI:N、機密性・完全性・可用性とも高)。CVSS v4.0 の値はなし |
| CVE | 未割り当て(勧告の識別子は GHSA のみ) |
勧告本文は「すべてのリリース」が影響を受けると書く一方、構造化データの対象範囲は 2.0.0 以上です。2.0.0 より前の系統の扱いは未確認です。
修正の中身
修正コミット 83689f0(10/18 UTC にマージ)は、次の変更を含みます。
- ファイル保存側で、パスを解決したうえで、リソース種別のディレクトリ直下のファイルでなければ拒否するようにしました。
- API 側で、リソース ID が空、
.、..、パス区切り、NUL を含む場合は拒否するようにしました(GET・PUT・DELETE とプログラムからの呼び出し、チャートの識別子にも適用)。 - カスタムのコレクション名が単一のパス要素でない場合は、追加時に拒否し、保存済みの設定からも取り除くようにしました。
- 試験として、ファイルストアとリソース API、アプリケーションデータ API の試験を追加しています。
このコミットが v2.34.0 に含まれることは、タグとの比較で確認しました(コミットはタグより前、タグの側が 6 コミット先)。
あわせて 2.34.0 では、JWT の署名鍵を security.json の外の専用ファイル(security-secret.key、所有者のみ)に移しています(PR #3192、10/18 UTC にマージ)。既存の secretKey は起動時に移されます。勧告の「提案する修正」の 3 点目に沿う変更です。2.34.0 より前に戻すと、署名鍵が再生成され、全利用者の再ログインと全機器のアクセス再申請が必要になります(PR の説明)。
対応
- signalk-server を 2.34.0 以上に更新します(執筆時点の npm の最新は 2.35.1)。resources-provider を単体で入れている場合は 1.5.3 以上にします。
- インターネットや船内の共有ネットワークから届く環境で、更新前に
allow_readonly=trueで動かしていたり、読み取り専用の利用者を発行していたりした場合は、署名鍵とパスワードが漏れた可能性を考えます。更新で鍵の保管場所は変わりますが、鍵の値自体が自動で作り直されるかは確認できていません。署名鍵の再生成(全トークンの失効)と利用者のパスワード変更を検討します(本記事の推定)。 - 設定の
providersに、見覚えのないExecute型のプロバイダーがないか確認します。あれば削除し、サーバーを動かしている利用者の権限で何が実行されたかを調べます(本記事の推定)。 - すぐ更新できない場合は、サーバーへのアクセスを信頼できるネットワークに限り、
allow_readonlyを無効にします。ただし読み取り専用のトークンがあれば成立するため、完全な回避策ではありません(本記事の推定)。
未確認の点
- CVE が未割り当てのため、NVD の評価、EPSS、KEV の掲載は照合できません。悪用の報告は確認できていません。
- 修正(10/18 UTC)から勧告の公開(10/30 UTC)まで約 12 日の経緯は未確認です。勧告の公開は 10/30 22:57 UTC です。
- 勧告本文の「すべてのリリース」と、構造化データの 2.0.0 以上との食い違い。2.0.0 より前の系統は未確認です。
- 2.34.0 への更新で署名鍵の値が自動で作り直されるかは未確認です。
- 実際の環境での再現は行っていません。記載は勧告と修正コミット、リリースノートに基づきます。
この記事について
- 執筆・編集
- World Security 編集部
出典
- GitHub Advisory GHSA-4xm8-rg9h-jhq2(GitHub)
- Signal K Server v2.34.0 リリース(GitHub)
- 修正コミット 83689f0(GitHub)
- PR #3192 JWT 署名鍵の保管場所の変更(GitHub)
- npm signalk-server(npm)




