Salesforce の SOQL インジェクション脆弱性 CVE-N/A:数百万のユーザーに影響をおよぼす可能性

Critical Salesforce Vulnerability Exposes Global Users to SOQL Injection Attacks

2025/06/09 gbhackers — Salesforce Aura コントローラーの、デフォルト・コンフィグに存在する SOQL (Salesforce Object Query Language) インジェクションの脆弱性を、あるセキュリティ研究者が発見した。この脆弱性により、数千のデプロイメントおよび、数百万のユーザーレコードに影響が生じる可能性がある。この発見が浮き彫りにするのは、動的なクエリ構築のリスクと、エンタープラ イズ・クラウドプラット・フォームにおける、セキュア・コーディングの重要性である。

発見および悪用の手法

Salesforce の app.js ファイル内で定義された、Aura コントローラーのエンドポイントに対して、研究者がテストしたのは、カスタム・パーサーとファジングを用いた多様な入力による変異である。このアプローチにより、以下のビルトイン・コントローラー に脆弱性が発見された。

“aura://CsvDataImportResourceFamilyController/ACTION$getCsvAutoMap”

このコントローラーは、すべての Salesforce デプロイメントに存在し、安全性が確保されていない方法で、動的 SOQL クエリに contentDocumentId を埋め込むため、インジェクション攻撃に対して脆弱であった。

この脆弱性は、以下のようなエラー・メッセージにより特定された。

json{
    "exceptionEvent": true,
    "useDefault": false,
    "event": {
        "descriptor": "markup://aura:serverActionError",
        "attributes": {
            "values": {
                "error": {
                    "message": "industries.impl.dataUtils.IndustriesDirectSoapUtil$DirectSoapException: MALFORMED_QUERY: \nContentVersion WHERE ContentDocumentId = '''\n                                          ^\nERROR at Row:1:Column:239\nunexpected token: '''",
                    "stackTrace": "",
                    "data": {
                        "message": "industries.impl.dataUtils.IndustriesDirectSoapUtil$DirectSoapException: MALFORMED_QUERY: \nContentVersion WHERE ContentDocumentId = '''\n                                          ^\nERROR at Row:1:Column:239\nunexpected token: '''",
                        "statusCode": 400,
                        "errorCode": "INTERNAL_ERROR"
                    },
                    "id": "-380442143"
                }
            }
        }
    }
}

このエラーは、ユーザーが入力した情報が、SOQL クエリにダイレクト挿入されていることを示す典型的な例であり、インジェクションのリスクを明確に示している。

SOQL の制限回避とデータ抽出の手法

SOQL は SQL に似ているが、UNION ベースの攻撃が不可能/サブクエリが制限されている/結合やマルチクエリ操作にも厳格な制約があるなど、いくつかの制限により悪用は困難である。

しかし研究者は、エラー・ベースのブラインド SQL インジェクションに類似した、レスポンスの不一致を利用し、データベースからの情報を推測する手法を確立した。

たとえば、以下のような巧妙に細工した contentDocumentId を送信することで、このサブクエリが成功した場合には有効なドキュメントが返り、失敗した場合にはエラーが生成されることから、このレスポンスの違いにより、サブクエリの結果を推測できる。

text069TP00000HbJbNYAV' AND OwnerId IN (SELECT Id FROM User WHERE Email LIKE 'a%25') AND ContentDocumentId != '

さらに Salesforce ID の予測可能な性質を悪用し、有効な contentDocumentId を生成するスクリプトを用いることで、ブルートフォース攻撃が達成され、所有者情報を取り込んだドキュメントの詳細を列挙できるという。

影響および緩和策のポイント

この脆弱性を悪用する攻撃者は、コンフィグの状態に応じて、ユーザーのメールアドレス/氏名/住所/パスワード・ハッシュなどの機密情報を抽出する可能性を手にする。

この問題は 研究者から Salesforce へと報告されたが、Salesforce はアドバイザリや CVE の発行を行わずに、この脆弱性をサイレント修正した。この対応は、セキュリティ欠陥への注目を避けたい大手ベンダーが、頻繁に採用する手法の一例である。

SOQL インジェクションを防ぐために、Salesforce および Apex 開発者コミュニティは、動的なクエリ構築ではなく、バインド変数を用いた静的クエリの利用を強く推奨している。

たとえば、以下の Apex コードには脆弱性がある。

textString qryString = 'SELECT Id FROM Contact WHERE (IsDeleted = false and Name like \'%' + name + '%\')';
List<Contact> queryResult = Database.query(qryString);

したがって、開発者は以下のようなコードを使用する必要がある。

textString qryString = 'SELECT Id FROM Contact WHERE IsDeleted = false and Name LIKE :name';
List<Contact> queryResult = Database.queryWithBinds(qryString, new Map<String,Object>{'name' => '%' + name + '%'});

この方法により、クエリ文字列へのユーザー入力のダイレクト挿入を防ぎ、インジェクション・リスクを大幅に軽減できる。

手法詳細説明防止方法
動的 SOQLユーザー入力を含む文字列としてクエリを構築するバインド変数を用いた静的クエリを使用する
エラーベース・インジェクションエラー・メッセージを利用してデータを推測する入力を検証し、サニタイズを実行する
ID ブルートフォース攻撃予測可能なオブジェクト ID を生成し、データにアクセスするレート制限とログ記録を実装

このインシデントが示唆するのは、セキュアなコーディングの実践と入力の検証に加えて、エンタープライズクラウド環境における、継続的なセキュリティ研究の重要性である。

開発者に対して強く推奨されるのは、動的 SOQL を取り込んだコードを見直して、より安全な代替手段を採用し、機密データを悪用から保護することである。