Mark Hammer's Blog

SalesforceやTrailheadに関する情報を投稿しているブログです。

Salesforce DX CLI で脆弱性とされた機能の紹介と対応策

はじめに

2021/10/4に、CERT/CCよりSalesforce DX CLIについてアクセス制限不備の問題が指摘されました。

jvn.jp

www.security-next.com

これに対し、Salesforceでは Salesforce ヘルプ: Salesforce Developer Experience Command Line Interface の設定 を公開しましたが、具体性がなく何が起きているのか分からない内容となっています。

ここでは、実際にどのような操作が問題なのか、また対応策について書いていきます。

注意事項

筆者は普段Salesforce DX CLIを使っておらず、一部憶測を含む部分があります。
本投稿の内容を試した際など、掲載内容からいかなる損失や損害などの被害が発生したとしても、当ブログでは責任を負いません。(サイトポリシーの免責事項もお読みください。)

問題となる事象と再現方法

Salesforce DX CLI には、登録した組織・ユーザにコマンド1つでログインできる機能があるのですが、そのコマンドを実行した際にそのユーザとして組織にログインできるURLが出力されます。
これが今回問題となった機能と思われます。

再現方法

  • Salesforce DX CLI をインストールする。
    • インストール方法はこちらを参照してください。
  • sfdx force:auth:web:login を実行し、ブラウザ画面からSalesforceにログインする。これにより Salesforce DX CLI 側に組織、ユーザ情報が登録される。
  • sfdx force:org:open を実行する。これにより sfdx force:auth:web:login コマンドでログインしたユーザと同じユーザでログインした状態でブラウザが起動すると同時に、そのユーザとして組織にログインできるURLが出力される。

実際のコマンド実行と出力内容の例です。

> sfdx force:auth:web:login -a test
# このコマンド実行後、Salesforceログイン画面が表示された状態でブラウザが起動する。
# この画面でログインすることで Salesforce DX CLI 側に組織、ユーザ情報が登録される。

> sfdx force:org:list
=== Orgs
  ALIAS  USERNAME             ORG ID              CONNECTED STATUS
  ─────  ───────────────────  ──────────────────  ─────────────────────
  test   test@sampleorg.com   00DxxYYYYYzzzzzAAA  Connected
# force:auth:web:login でログインした情報が表示される

> sfdx force:org:open -u test
WARNING: This command will expose sensitive information that allows 
for subsequent activity using your current authenticated session.
Sharing this information is equivalent to logging someone in under the 
current credential, resulting in unintended access and escalation of privilege.
For additional information, please review the authorization section of the 
https://developer.salesforce.com/docs/atlas.en-us.234.0.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_web_flow.htm

Access org 00DxxYYYYYzzzzzAAA as user test@sampleorg.com with the following 
URL: https://mysampledomain.my.salesforce.com/secur/frontdoor.jsp?sid=00DxxYYYYYzzzzz!heersgKJolaf0kq3rLMODASA...
Waiting to resolve the Lightning Experience-enabled custom domain...... done

上記コマンドの https://mysampledomain.my.salesforce.com/secur/frontdoor.jsp?sid=00DxxYYYYYzzzzz!heersgKJolaf0kq3rLMODASA... が「そのユーザとして組織にログインできるURL」です。
上記URLの sid はセッションIDを指すと思われます。つまりこのURLを悪用すればセッションハイジャックができてしまうということです。

cybersecurity-jp.com

なぜURLを出力しているのか

Salesforce DX CLI では、スクラッチ組織という開発者が開発のために作ることができる組織があります。(Developer Edition組織とは別です。)

trailhead.salesforce.com

この「スクラッチ組織を使って開発する」ことを考えたときに、複数人でチームとして開発しており、開発の内容をチーム内で確認してもらいたいときは「スクラッチ組織に開発者全員のユーザアカウントを作成してアクセスしてもらう」よりも「システム管理者としてログインできるURLを発行してそれをチーム内に連携する」方が便利です。
(「スクラッチ組織を作成→その組織にログイン」の流れが force:org:createforce:org:open とコマンドで完結し、ログイン画面を介さないため「ユーザ名とパスワードを連携する」という方法も不便になってしまう。)

よって、Salesforceとしてはこの機能は開発用に用意したものであり、本番環境はセッションハイジャックを防ぐためにセッション設定を用意しているのでそれを適用するように、というのが見解だと思われます。

対策方法

発行されたURLはログイン済のセッションを用いているため、ユーザ名、パスワードはもちろん多要素認証を必須にしていたとしても多要素認証の情報なしにログイン後の画面にアクセスできてしまいます。
さらに、ログイン履歴にもこのURLを用いたアクセスは記録されません。(アクセス後にレコードを参照すると、「最近参照したレコード」として記録はされます。)

発行されたURLからの外部アクセスを防ぐためには「セッションの設定」にて防止用の設定を導入する必要があります。 具体的には以下2点です。

ログイン時の IP アドレスとセッションをロックする

これはログイン時のIPアドレスとログイン後のIPアドレスが変わった場合にそのセッションを切断し、再度ログインを要求する機能です。
これにより、 Salesforce DX CLI で発行されたIDに外部からアクセスしようとしてもログイン画面に戻されます。
ただし、「ログイン時の IP アドレスとセッションをロックする」を有効にした後のログインが対象となります。有効にする前にログインした際のセッションはこの機能の制限を受けません。

これを有効にするとSalesforceアクセス後に自分の端末のIPアドレスが変わるとログイン画面に戻されることになります。(ノートPCやスマートフォンでは影響があるでしょう。)
また、Salesforceヘルプ: セッションセキュリティ設定の変更 にも「この設定は、さまざまなアプリケーションやモバイルデバイスの機能を妨げる可能性があります。」という注意書きがありますので、安易な設定はお勧めできません。

すべての要求でログイン IP アドレスの制限を適用

これはログイン IP アドレスの制限が設定されているユーザにてログイン後にIPアドレスがログイン IP アドレスの制限の範囲外になった場合、エラーとする機能です。

エラー画面

これも同様に、Salesforce DX CLI で発行されたIDにログイン IP アドレスの制限範囲外となる外部からアクセスしようとしてもエラーになりますが、Salesforceアクセス後に自分の端末のIPアドレスがログイン IP アドレスの制限範囲外になった場合もエラーになります。(ノートPCやスマートフォンで、VPN使用時にVPNが切断された場合などが該当するでしょう。)

備考

ここでは2つの設定を紹介しましたが、いずれにも言える点は「たとえ有効にしたとしてもセッションハイジャックを完全に防ぐことはできない」という点です。
具体的にはどちらの設定もログイン後にIPアドレスが変わったことをトリガとしてエラーとするため、「社内で Salesforce DX CLI により発行されたURLを盗み見てアクセスすればセッションハイジャックできる」といった内部犯行を防げません。(社内のPCに対しグローバルIPアドレスを個別に割り振っているのであればこのような内部犯行は防げますが、そのような会社はごく少数でしょう。)

よって、セッションハイジャックを完全に防ぐ方法として「本番環境では force:org:open を使わない」を提案します。
そもそも force:org:open はスクラッチ組織のためにあるものだと考えれば、ユーザ名、パスワードを入力すればログインできる本番組織には不要とも言えます。
コマンド1つでログイン画面が表示できるのは便利ではありますが、セキュリティを考慮すると本番環境では使わない方がよいと考えます。

おわりに

今回の問題はゲストユーザ問題と同様、責任共有モデルが大きく関わってきます。
つまり「Salesforceはセッションハイジャック防止用の設定を用意しているので、ユーザの責任で導入してください。」というものです。
しかし先述の通りアクセス元IPアドレスが変わらない状況にてセッションハイジャックを防ぐ機能がSalesforceにない現状では、片手落ちの印象も受けます。

本件について記載されたヘルプでは「今後、機能拡張があった場合は、この記事を更新します。」とのことですので、何らかの機能拡張があるか注目したいと思います。