アンチパターンから考える Salesforce ゲストユーザ問題

本記事の内容は可能な限り正確な情報を記載するよう努めていますが、
必ずしも内容の正確性や安全性を保証するものではありません。
当記事を参照・利用したことによってトラブルが発生しても一切の責任を負いかねます。
また、本記事にて記載している検証行為はすべて筆者の developer 環境で行っております。

はじめに

2020年の末ごろから、Salesforce の設定不備による情報漏洩を伝えるニュースが立て続けに報じられるようになりました。

この問題を一番よく伝えているのは日経クロステックで、同紙によると現在までに、多数の企業で影響があったとされています。(注:ただし、報じられている企業の多くは、プレスリリースでは「クラウド型システム」というような表現に留めており、Salesforce のことであるとは発表しておりません)

また、02/12には両備システムズから Salesforce を利用した自治体向けのシステムでも同様の問題が生じたことが発表され、この問題は企業だけでなく多数の自治体・団体にまで波及する事態となっています。

これに対して Salesforce は12月25日から各種のアナウンスを出して、導入各社に設定を見直すように呼びかけを行っていますが、Salesforce のお知らせは、ゲストユーザに対する共有に関する設定がお客様の用途に沿った設定になっているかどうかはお客様にご確認いただく必要がございます というスタンスの案内となっています。

そのために具体的に何をどうすればよいのか、何が間違いであるのか、間違えた場合に何が起きるのかを理解しづらい状況になっており、まだ問題を抱えながらも修正できていない管理者がいるのではないかと思われます。

実際に、02/10 に公表された西条市のプレスリリースでは、他社事例の存在を把握しながらも問題に気付けなかったことが経緯に記されています。

経緯
令和2年12月29日
受託事業者が、本システムに係るセキュリティ上の問題に関する注意喚起情報及び2つの対策について関連事業者から提案を受けて同事業者と協議・検討した結果、設定変更は必要ないと判断
令和3年1月20日
内閣サイバーセキュリティセンター(以下「NISC」)から総務省経由で市に対し、「本システムについて、意図しない情報が外部から参照される可能性がある旨」の注意喚起を受けたため、市から受託事業者に対して調査開始を指示(市はこの時点で認知)
1月22日
受託事業者から市に対し「問題なし」との回答あり
1月23日
市から総務省へ「問題なし」と報告
1月27日
再度、NISCから総務省経由で市に対し、「申請者の一部情報が参照できる可能性がある製品について、各種設定の確認・見直しを行うなど、適切なセキュリティ対策を講じるよう」との連絡があり、受託事業者に再確認と対処を指示
1月29日
受託事業者において指示内容を検討した結果、本システム設定の一部を変更する対策を実施
2月1日
受託事業者が不正アクセスに対するすべての設定変更を実施
2月5日
受託事業者の調査(ログの解析)により、不正アクセスの事実(1月9日及び12日にアクセス)が判明本システムを閉鎖し、利用者全員に注意喚起のメールを配信

プレスリリース:「総合健診Web予約システム」への不正アクセスに関するご報告



そこで逆に考えて、情報が漏洩してしまうような設定や実装例を実際に作ることで、
この問題が理解しやすくなるのではないかと思い、本記事を書いてみることにしました。

一連の問題に対する Salesforce からのアナウンス

以下のようなアナウンスを公表しています

流出の原因とみられるアクセス経路

Salesforce 社は現時点(2021/02/13)でこの一連の問題の詳細な原因を公表していません。
しかし、いくつかの公開されている情報から、この問題の流出経路を推測することができます。

Teamspirit の発表

まず、Teamspirit は12/29のリリースで、2020/12/25 の Salesforce 社のプレスリリースを参照したうえで、具体的に Sites 機能を用いたシステムで問題があったことを発表しています。

2020年12月26日の当社発表(※1)のとおり、株式会社セールスフォース・ドットコムの発表をうけて調査を継続しておりました当社が利用する対象製品(※2)の影響範囲にかかる調査が終了いたしましたのでご報告いたします。

調査の結果、現在は利用されていませんが、「Salesforceサイト」を用いた2つのシステムにおいて、ゲストユーザへの情報共有に関する設定が本事象(※3)の生じる条件下にあったことを確認いたしました。これらのシステムは既に設定を変更し本事象の生じない状態となっております。

https://www.teamspirit.com/ja-jp/news/release/post-20200513.html

発端となったと思われるブログ記事

また、昨年の10月に海外のセキュリティ研究者が以下のブログを公開しており

その中で aura endpoint (以降「Auraエンドポイント」と記す)と呼ばれるURLに特定のリクエストをPOSTすると、ゲストユーザが参照できるレコードを得ることができるのをはじめ、様々な操作ができることを紹介しています。

日本では昨年末に次の2つのブログでこのブログ記事と一連の問題を紹介しており、去年からこの問題をウォッチされている方にとってはおなじみの記事ではないでしょうか。

日経クロステックの報道

最後に、日経クロステックで、原因は「Auraエンドポイント」と呼ばれる機能であると報じられています。

トラブルの火種になったのは、Lightning Experienceのリリース当初から部品の1つとして提供されていたとみられる「Auraエンドポイント」だ。同部品を使うと、セールスフォース製品が従来備える「オブジェクト」と呼ばれるデータベースに対し、第三者が「ゲストユーザー」の権限で直接アクセスできるようになる。ゲストユーザーとはアンケートフォームへの回答者などセールスフォースのサービスのアカウントを持たない人を指す。
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/092400133/012800042/



これらの情報を合わせると、一連の問題の流出経路は「元ブログ」で紹介されている手法を用いて、ゲストユーザが参照可能なレコードをAuraエンドポイントを通じて取得されたと見て間違いなさそうです。

実際に公開されている方法を試してみましょう

では実際に外部からレコードの情報を取得されてしまうような状況を作って、Auraエンドポイントからデータにアクセスされるとはどのようなことなのかを確かめてみましょう。
例では「取引先」オブジェクトで試してみます。

前章で挙げた3つのブログ記事から、このAuraエンドポイントによるレコードの取得は以下の条件を満たすときに機能することが分かっています。

  • サイトとその「ゲストユーザ」が有効である
  • ゲストユーザが参照できるレコードが存在する
  • サイトの詳細設定画面で「ゲストユーザの Lightning 機能」が有効になっている

この状況を作ったうえで、元ブログの内容からPOSTリクエストを作成して、実際にレコードが取得できるか実験します。

  1. サイトを作成して「ゲストユーザの Lightning 機能」を有効にする
    (2/16 追記)「ゲストユーザの Lightning 機能」はデフォルトでONなので、変更せずとも有効化されていると思います。またコメント欄に @yumano さんより、サイト以外の同機能の設定についてコメントいただいています。あわせてご覧ください。 image.png
  2. オブジェクトとそのレコードをゲストユーザから参照可能な状態にする
    問題を再現するためにゲストユーザがレコードを参照できるよう設定を追加します。

    1. オブジェクトと項目の参照権限をゲストユーザに付与する(作成権限もついていますが気にしないでください) image.png
    2. オブジェクトのレコードをゲストユーザから参照できるように共有設定をする image.png
  3. テストデータを適当に作る
    image.png

  4. 実際にAuraエンドポイントにリクエストをPOSTする
    以下は取引先(=Account)オブジェクトでゲストユーザが参照できるレコードの一覧を取得するリクエストで、そのレスポンスには先ほど作成した取引先のレコード testAccount の情報が含まれていることがわかります。
    image.png
    Salesforce は一連の問題に脆弱性は無いと言っているので、このPOSTリクエストは公開しても問題ないと思います。(実際Lightning 機能を利用しているページでは、ブラウザからAuraエンドポイントに対する通信は普通に行われるようです)
    しかし、濫用防止のためにリクエストの一部分を伏せさせていただいています。実際のリクエストパラメータの作り方については元ブログを参照してください。

レコードがゲストユーザから参照される条件

ゲストユーザがレコードに対してアクセスできる状態とは、ひとつの設定によるものではなく複数の設定の組み合わせの結果に生まれる状態を意味します。
具体的には

  • 所有者
  • 組織の共有設定
  • オブジェクトの共有ルール
  • オブジェクトの参照権限
  • オブジェクト内の項目の参照権限
  • ロール

などなどですが、これを解説すると記事1本分の長さになってしまうのでこちらについては他の方が書かれた記事、または、Trailhead のデータセキュリティの章を参照してください。

うちも不安...という方向けのsalesforceアクセス権を安全に保つ5つの確認箇所
Trailhead データセキュリティ

また、ゲストユーザの場合は昨今の仕様変更により徐々に制限が厳しくなっているなど、
仕様を正確に把握するのはなかなか面倒です。(spring'21 のリリースでもまた変更があります)
winter'21以降ではレコードの所有者にゲストユーザを新たに設定したり、組織の共有設定やキューによってゲストユーザに対して参照権限を付与することはできません。

ゲストユーザのセキュリティポリシーとタイムライン
ゲストユーザの共有設定とレコードアクセスの保護
[ゲストユーザの組織の共有設定と共有モデルの保護] の無効化不可

Salesforce のアナウンスで公表されていないこと

Aura エンドポイントについて

そもそもにおいて、このAura エンドポイントと呼ばれているAPIに関するドキュメントは見当たりません。
このAPIが一体どういうものなのか、リストを取得する際に呼ばれている SelectableListDataProviderController とはどういう機能であるのかは現時点では不明です。

「ゲストユーザのLightning機能」について

事実として、サイトの設定画面の「ゲストユーザのLightning機能」のチェックを外すと、先の漏洩を起こすリクエストを受け付けなくなります。
今まさに本手法により情報漏洩してしまう状態になってしまっているならば、この設定をOFFにすることでとりあえずの止血ができると思うのですが、Salesforce はこの点についても何も言及していないので断言はできません。
image.png
チェックを外して、先ほどのリクエストを再度 POST すこと、404を返すようになります。

アンチパターンに陥りやすいと思われる実装例

実際に情報漏洩が起きてしまう様子はわかりました、では次にこの状況を生み出してしまうようなサイトの実装について考えてみましょう。

この問題を引き起こしやすいのは、やはり visualforce の Apex:inputField を 使ってオブジェクトに紐づいたフォームを作った場合ではないかと思います。なぜかというと、この Apex:inputField を使うとオブジェクトに関連した入力フォームを作ることができますが、オブジェクトと項目に対してゲストユーザの作成権限を付与しなければならず、漏洩状態の条件の一つを作り出してしまうためです。(これ単体では条件を満たしません)

Apex:inputField を使ったフォームの実装例

サンプルとして取引先(Account)の名前と電話番号を入力するシンプルなフォームを作ります

  1. コントローラを用意
    image.png

  2. visualforce ページを用意
    image.png

  3. オブジェクトの作成権限と、項目の編集アクセス権を付与
    image.png

  4. サイトの設定でページを追加
    image.png

  5. 簡易な入力フォームの完成
    これでページ名をパスにしてアクセスすると、あっというまにフォームが出来上がりました
    image.png

  6. オブジェクトとその項目にゲストユーザの権限が無いと機能しない
    しかしこのフォームはオブジェクトと項目に対するゲストユーザの権限がないと機能しません
    これは取引先の項目の権限から電話番号を抜いた場合の表示例です。このように権限がないとフォームが表示されなくなります。
    image.png

登録フォームだけなら直ちに問題ではない

このような実装でレコードを登録するフォームを公開しただけの場合は、直ちに情報漏洩につながるわけではありません。
これは作成したレコードにゲストユーザからアクセスする権限を付与していないためで、レコードのゲストユーザ共有ルールなどを設定しない限りは問題ありません。前の章で実験したときは外部からアクセスできるようにその設定を追加していました。

例外としてはオブジェクトの参照権限の「すべてのデータの変更」「すべてのデータの参照」があります。
この設定はいろいろオーバーライドするのでややこしいです。しかしこの権限も spring'21 でゲストユーザからは削除されました。
「すべて表示」および「すべて変更」権限の概要

所有者 "ゲストユーザ" 問題

ところが以前はこの実装にも問題がありました。レコードの所有者が"ゲストユーザ"になってしまう場合です。
winter'21 以降はゲストユーザがレコードの所有者になることは無くなりました。
ゲストユーザによって作成されたレコードのデフォルトの所有者への自動的な割り当て

しかし、この変更が適用される前に作成されたレコードで所有者がゲストユーザであるものは、現在においてもそのままになっている可能性があります。
この点見落としがちであると思うので、心当たりのある方は既存レコードの所有者を再点検することをお勧めします。

詳しくは Salesforce の資料[JP] Salesforce_ゲストユーザセキュリティ_ベストプラクティスの解説 (要 Trailblazersコミュニティログイン)の「確認項目2-5 レコードの所有者」を確認してください。

編集フォーム(winter'21 以前)や、レコードを参照する処理は要注意

spring'21 によってゲストユーザのオブジェクトに対する「編集」「削除」「すべてのデータの変更」「すべてのデータの参照」の権限が削除されて先述のような apex:inputField を用いて、レコードを編集するようなフォームを簡単に作成することはできなくなりました。

逆に言うと今まではそれができたわけで、ゲストユーザからレコードへの参照・上書きを伴うフォームが存在することは、それほど不思議ではないと思います。(URLのパラメータに、レコード ID とトークンなどを持たせることでそれなりに安全に実装できました)
しかし、その実装をするためには、ゲストユーザがレコードを参照・編集できる必要があるために、今回の問題を引き起こす"設定不備"につながりやすかったのではないかと思われます。
現在は without sharing を利用してシステムコンテキストで実行するような実装が多いのでしょうか。(普段サイトを使わないので、間違っていたらすいません。)

余談ですが spring'21 適用によってそのような編集フォームが使えなくなってお困りの方は、こちらの資料も参考にするといいかもしれません。
Guest User Record Access Development Best Practices

このような実装はベストプラクティスではなかったのか?

apex:inputField を使ってオブジェクトに紐づいたフォームを実装するのは普通のことではないかと思います。
なので、レコードに対する参照設定が問題の本質とは思いますが、古い資料にはそのあたりの記述が見当たらないために、2018年以前からそういう観点があったのかどうかはわかりません。

  • Salesforceで、取引先責任者の登録フォームをつくる方法
    2014年に書かれたこちらのブログは先ほど紹介した方法と同じで、apex:inputField を使ってオブジェクトに対応したフォームを作っています。

  • Learning Apex Programming
    2015年に出版された書籍ですがChapter6(P141~147)で visualforce ページをサイトで公開する手順について記されています。
    ここでも apex:inputField を使ってオブジェクトに対応したフォームを作っています。所有者や共有設定についてについて特に記述はありませんでした。
    なお著者の一人 Matt Kaufman 氏は執筆当時 salesforce.com スタッフであると紹介されています。

  • Trailhead Web サイトインテグレーションの開始
    私が探した限り、Trailhead で唯一のサイトに関するガイドがあったものです。AppExchange でインストールしたサイトをセットアップする手順が記載されていますが、現在のゲストユーザでの仕様では設定できない内容を含みます。ここでは当時はゲストユーザにも有効だった「組織の共有設定」をしていて、取引先責任者に「公開/参照・更新可能」を設定して、項目の参照権限も与えています。ちょっと?な感じではありますが、今の仕様に無い設定は検証できないので何とも言えません。

まとめ

  • 最近話題になっている Salesforce の設定不備による情報流出事故について、流出方法とされてるアクセス方法や、その状況を作りやすい実装について検証しました
  • この問題は複数の設定の組み合わせで発生するので、 "単なる設定ミス" といえるほど単純ではありません
  • 実際に手を動かして試してみることをおすすめします
    普段サイトを使っていなくても、レコードに対する権限設定を理解するためには良い題材であると思います。私も知らなかったことを新たに知ることができました。
  • Salesforce のサイトで、フォームを作っている人はは今一度設定を再確認しましょう
    特に 2019年以前に作成されたレコードで、所有者がゲストユーザのままになっているものが残っていないかチェックしましょう
  • 不明なことはは SF のサポートに聞いてください
  • セールスフォースはできればプレスリリースを消さないでください(12/25 のプレスリリースのことです)

【余談】自治体向けのシステムで事故が起きたことについて

今回の一連の問題は、民間企業だけでなく、自治体のシステムにおいても流出事例が起きる事態となりました。
自治体のシステムで問題が起きることは、民間のサービスで問題が起きることとは意味合いが異なります。
それは、公共サービスはその地域の住人の税金によってほぼ独占的に運営され、仮に Salesforce が嫌いだからと言っても、他を選択することができないからです。また、クラウドサービスは一度導入されると乗り換えや管理者の変更が難しいため、固定化されてしまいがちな問題もあります。(コロコロ変えていいものでもないですが)

ですから、西条市のケースのように問題に気付きながらも難解なアナウンスのために要点を理解できず対応が遅れ、本来防げたはずの不正アクセスが行われたかもしれないことや、Salesforce でありがちなログの入手や監視の難しさ(端的に書くと別料金が必要)といったような事柄については、導入していた自治体は強く改善を求めるべきだと思います。

加えて、両備システムズの i-Blend はセールスフォース社自身もプッシュしていたことが確認できるので、この自治体システムの問題に関しては Salesforce 社も他人事というわけにはいかないはずです。
salesforce-solutionguide-p10.PNG
Salesforce ソリューションガイド 住民向けモハイルアフリ構築フラットフォームi-blend



以上となりますが、Salesforce 社にはこれ以上の被害が拡大しないためにも、よりいっそう丁寧なアナウンスとサポートをしていただきたいと思います。
正しいことを言うよりも。。。なんでしたっけ?御社のCMで何か言っていた気がしますが言うだけではないですよね。



追記

(02/16)
誤字と軽微な表現の修正をしました。
両備システムズのプレスリリース(第3報)を資料に追加
「ゲストユーザの Lightning 機能」のデフォルト値について追記



参考資料

プレスリリースなど

報道記事

Salesforce

その他web

書籍






tonnuts
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
ユーザーは見つかりませんでした