進行状況の追跡を始めよう
Trailhead のホーム
Trailhead のホーム

標準のオープンリダイレクト防止の概要

学習の目的

この単元を完了すると、次のことができるようになります。
  • 標準のリダイレクト保護で対象となる 4 つのリダイレクトパラメータを挙げる。
  • カスタムアプリケーションでデフォルトの Salesforce オープンリダイレクト保護が失敗するケースを識別する。

安全な Salesforce のリダイレクト

前の単元で確認したように、リダイレクトは多くの開発者が利用している標準のアプリケーション機能です。Salesforce のコア製品でさえ、アプリケーションにリダイレクトが含まれているので皆さんも慣れているでしょう。

パラメータ 使用方法
startURL ページ読み込み時にユーザをある場所にリダイレクトするために使用
retURL ユーザが [Back (戻る)] ボタンをクリックすると、そのユーザをある場所にリダイレクトするために使用
saveURL ユーザが [Save (保存)] ボタンをクリックすると、そのユーザをある場所にリダイレクトするために使用
cancelURL ユーザが [Cancel (キャンセル)] ボタンをクリックすると、そのユーザをある場所にリダイレクトするために使用

Salesforce リダイレクトの探索

前の単元では、これらのパラメータをユーザに公開すると、ユーザはオープンリダイレクト攻撃に対して潜在的に脆弱になることを学習しました。では、Salesforce は脆弱なのでしょうか? 調べてみましょう。
  1. Kingdom Management 開発者組織にログインして、Open Redirect アプリケーションを選択します。
  2. [Standard Redirect Protections Demo (標準のリダイレクト保護デモ)] タブをクリックします。
  3. いずれかの内部リダイレクトリンクをクリックします。
    標準の salesforce レコード編集ページにリダイレクトされます。このページでは、前述した retURL パラメータを使用してリダイレクトを処理します。
  4. [保存] をクリックします。

    リダイレクトは期待どおり機能します — アプリケーションは [Save (保存)] が選択されると、前に表示されていたタブにユーザを戻します。

  5. [Standard Redirect Protections Demo (標準のリダイレクト保護デモ)] タブに戻ったら、外部リダイレクトリンクのいずれかをクリックします。アプリケーションは前と同じ編集ページにリダイレクトしようとしますが、今回 retURL の値は外部でホストされている動画へのリンクに設定されています。

    次のようなエラーメッセージが表示されます。 リダイレクト失敗

    どうなっているのでしょうか? なぜ標準ページは外部リダイレクトパラメータ値を受け入れないのでしょうか? これは、デフォルトの Salesforce オープンリダイレクト保護が効いているからです。すべての標準ページでは、デフォルトで外部リダイレクトがブロックされます。

  6. アドレスバーの retURL の値を https://www.google.com や https://www.salesforce.com のような別のパラメータ値に編集してみてください。

    https://www.salesforce.com を試したときはエラーメッセージが表示されません。この保護は、*.salesforce.com、*.visual.force.com、および *.content.force.com 空間内にあるドメインにのみ安全にリダイレクトするように設計されています。それ以外の場合はエラーメッセージが表示されます。この動作を調べるには、さまざまな URL を試してエラーメッセージが表示される URL を確認します。

カスタム Visualforce/Apex での Salesforce の標準保護

Kingdom Management 開発者組織では、カスタムアプリケーションを使用して、物資をさまざまな城に移送するための物資要求を表示し、ユーザが編集できるようにしています。ユーザがレコードを編集した後に [Save (保存)] をクリックすると、リダイレクトしてホームページに戻ります。次のコードがアプリケーションでこの機能に使用されます。

Visualforce:
<apex:commandButton action="{!save}" value="Save"/>
Apex:
	public PageReference save(){
		PageReference savePage;
		if (Schema.SObjectType.Requisition__c.isUpdateable()){
			try{
                update requisitions;
                String onsave = ApexPages.currentPage().getParameters().get('retURL');
                onSave = (onSave == NULL) ? '/home/home.jsp' : onSave;
                savePage = new PageReference(onSave);
                savePage.setRedirect(true);
                return savePage;
			}catch (exception e){
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'Unable to update requisitions.  Exception: ' + e.getMessage()));
                return null;
			} 
		}else{
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'You do not have permission to update requisitions'));
            return null;
		}
	}

ご覧のとおり、ユーザが Visualforce ページで [Save (保存)] をクリックすると、Apex の save 関数がコールされます。save 関数が retURL URL パラメータの値を取得し、対象ページへのリダイレクトを実行します。オープンリダイレクト攻撃のデモを行う前に、この URL パラメータを利用するアンチパターンを確認しましたが、デフォルトの Salesforce リダイレクトパラメータを使用していれば安全なのでしょうか? 調べてみましょう。

  1. Kingdom Management 開発者組織で、アプリケーションピッカーから Open Redirect アプリケーションに移動します。
  2. [Visualforce Anti-Protections Demo (Visualforce 保護無効デモ)] タブを選択します。
  3. URL バーの retURL パラメータを /home/home.jsp から https://www.google.com のような外部 URL に変更してページを送信します。

    エラーメッセージが表示され、外部 URL が保存されるのを防止します。

  4. もう一度試します。今回は retURL パラメータの大文字を retURL から returl に変更します。新しい URL は、https://c.[yourinstance].visual.force.com/apex/visualforce_anti_protections_demo?returl=https%3A%2F%2Fwww.google.com のようになります。
  5. ページ下部にある [Save (保存)] ボタンをクリックします。

    まだリダイレクトが行われています! どうなっているのでしょうか?

残念ながら、デフォルトの Salesforce 標準ページのリダイレクト保護は、カスタム Visualforce および Apex に対して完全には拡張されていません。デフォルトでは、Salesforce は標準のリダイレクトパラメータ retURLstartURLcancelURLsaveURL に対してのみ基本のリダイレクト保護を提供します。ただし、この保護では大文字と小文字が区別されるため、retURL を returl に変更すると、プラットフォームでそのパラメータが認識されません。

Apex に慣れている方なら、Apex では大文字と小文字が「区別されない」ことをご存じでしょう。retURL パラメータを解析する Apex コードに戻りましょう。

	String onsave = ApexPages.currentPage().getParameters().get('retURL');

このコード行は、その値の大文字と小文字の任意の組み合わせ (retURLRETURLreturlrETurl など) を受け入れますそのため、このプラットフォームに詳しい攻撃者は、リダイレクトパラメータの大文字と小文字を変更するだけで、プラットフォームが設定したデフォルトの保護を迂回できます。

この重要な点を、多くの開発者が把握していません。プラットフォームは、標準ページではこれらのリダイレクトパラメータを安全に使用していますが、多くの開発者はこのパラメータを使用でき、同じ保護を自分のコードにも拡張できると考えています。ただし、デモで見たように、そうではありません。

そのため、コード内のリダイレクト先がユーザに公開される場所 (URL パラメータやフォーム項目など) でリダイレクトを実行する場合は、コードに保護レイヤを追加する必要があります。次の単元では、これを実現するためのさまざまな戦略を確かめながら学習します。

retargeting