15 Oracle JETアプリケーションの保護

Oracle JETは、Oracle JETコンポーネントのセキュリティ・ベスト・プラクティスに準拠し、ユーザーの個人データへのアクセスを管理するのに役立つOAuthクラスを提供します。

Oracle JETアプリケーションの保護について

Oracle JETアプリケーションは、JavaScriptで記述されたクライアント側のHTMLアプリケーションです。Oracle JETアプリケーションを保護するためのベスト・プラクティスに従う必要があります。

Open Web Application Security Project (OWASP)Web Application Security Project (WASP)Web Application Security Working Group (WASWG)など様々な商用サイトから、役に立つ多数のインターネット・リソースを入手できます。

Oracle JETコンポーネントおよびセキュリティ

Oracle JETコンポーネントは、セキュリティのベスト・プラクティスに準拠します。具体的には:

  • すべてのJavaScriptコードは、use strictディレクティブを使用してstrictモードで実行されます。

    Strictモードでは、不正な構文(宣言されていない変数の使用など)に関する警告が、修正が必要な実際のエラーに変わります。詳細は、http://www.w3schools.com/js/js_strict.aspを参照してください。

  • Oracle JETコードでは、インラインのscript要素を使用しません。

    ブラウザではインライン・スクリプトがどこで発生したかを認識できないため、World Wide Web Consortium (W3C)のContent Security Policyでは、インライン・スクリプトの使用を禁止しています。詳細は、https://w3c.github.io/webappsec/specs/content-security-policyを参照してください。

  • Oracle JETコードでは乱数を生成しません。

  • Oracle JETコンポーネントで生成されたHTMLは、エスケープまたはサニタイズされます。

Oracle JETのセキュリティおよび開発者の責任

Oracle JETコンポーネントは、確立されたセキュリティ・ガイドラインに準拠しており、XSS攻撃を防ぐために、オプションとして提供される文字列およびユーザー入力がJavaScriptとして実行されることはありません。ただし、Oracle JETには文字列をサニタイズするメカニズムが含まれていないため、確立されたガイドラインを参照して、独自のコードおよびコンテンツでXSS攻撃に対処する必要があります。

JavaScriptアプリケーションの保護の詳細は、DOMベースXSS対策チート・シートを参照してください。

Oracle JETのセキュリティ機能

Oracle JET APIには、OAuth 2.0オープン・プロトコルをサポートするOAuth認可プラグインが用意されています。OAuthは、デスクトップおよびWebアプリケーションがユーザーの個人データにアクセスする方法を標準化します。個人のユーザー名とパスワード資格証明を共有せずに、ユーザーに個人データへのアクセス権を付与するメカニズムを提供します。

OAuth 2.0は、次のロールを定義します。

  • リソース所有者: 保護されているリソースへのアクセス権を付与できるエンティティ(エンド・ユーザーなど)。

  • クライアント: リソース所有者のかわりに、保護および認証されているリソースのリクエストを作成するアプリケーション。

  • リソース・サーバー: アクセス・トークンを使用して保護されているリソースのリクエストを受け入れて応答できる、保護されているリソースをホストするサーバー。

  • 認可サーバー: リソース所有者を正常に認証し、認可を取得した後で、クライアントにアクセス・トークンを発行するサーバー。認可サーバーはリソース・サーバーと同じサーバーであることが可能です。さらに、認可サーバーは、複数のリソース・サーバーによって受け入れられるアクセス・トークンを発行できます。

OAuth 2.0 Request for Comments (RFC) 6749では、次の概念フローに示すように、4つのロール間の相互作用が説明されています。

  1. クライアントは、直接または認可サーバーを介してリソース所有者からの認可をリクエストします。RFCでは、認可サーバーが優先されることが示されていることに注意してください。

  2. クライアントは、リソース所有者の認可を示す資格証明として定義された認可付与を受け取ります。

  3. クライアントは、サーバーで認証し、認可付与を提示して、認可サーバーからアクセス・トークンをリクエストします。

  4. クライアントを認可して認可付与を検証した後に、認可サーバーはアクセス・トークンを発行します。

  5. クライアントは、アクセス・トークンをリソース・サーバーに提示し、保護されているリソースをリクエストします。

  6. リソース・サーバーは、アクセス・トークンを検証し、検証された場合はリクエストに応答します。

アクセス・トークンはサーバーが発行する一意の識別子で、認可がリクエストされたか、またはクライアントによって認可が取得されたリソース所有者に、認可されたリソースを関連付けるためにクライアントで使用されます。

Oracle JETのOAuthプラグインによって、次のタスクを実行するための機能が提供されます。

  • アクセス・トークン資格証明の取得(クライアント資格証明で初期化された場合)。

  • アクセス・トークン資格証明のキャッシュ。

  • Bearerトークンを使用したヘッダー配列の作成。

OAuthプラグインの使用の詳細は、「Oracle JETアプリケーションでのOAuthの使用」を参照してください。OAuth 2.0の詳細は、https://tools.ietf.org/html/rfc6749を参照してください。

Oracle JETのセキュア・レスポンス・ヘッダー

Oracle JETでは、Oracle JET WebアプリケーションをセキュアにホストするためにHTTPレスポンス・ヘッダーを使用することをお薦めします。これらのレスポンス・ヘッダーによって、Webアプリケーションはクロス・スクリプティング(XSS)攻撃、パケット盗聴およびクリックジャック攻撃から保護されます。

JETアプリケーションがホストされているサーバーでこれらのレスポンス・ヘッダーを構成する必要があります。これらのレスポンス・ヘッダーの構成はサーバーのタイプによって異なるため、構成ステップについてはサーバーのドキュメントを参照してください。

XSS攻撃やパケット盗聴を制御するには、セキュア・レスポンス・ヘッダーを使用し、ユーザー・エージェントに対して、指定されたサイトにHTTPS経由でのみ接続し、セキュアなチャネルを介してすべてのリソースをロードするように通知する必要があります。サーバーでレスポンス・ヘッダーを構成して、使用が許可されるプロトコルを指定できます。たとえばサーバーは、すべてのコンテンツがHTTPSプロトコルを使用してロードする必要がある旨を指定できます。

クロス・スクリプティング攻撃やパケット盗聴を減らすために、HTTPSプロトコルを使用してJETアプリケーションをホストすることをお薦めします。また、新しいブラウザ機能の一部は、HTTPSプロトコルでのみ動作します。次の表には、セキュア・レスポンス・ヘッダーの一部と、そのうちのどのヘッダーがHTTPSベースの構成に固有であるかを示すHTTPS列がリストされています。

表15-1 セキュア・レスポンス・ヘッダーのオプション

オプション HTTPS関連 説明

Content-Security-Policy

表15-2「Content-Security-Policyヘッダーのオプション」を参照してください。

いいえ

ファイングレイン・リソース・アクセスを指定します。

X-XSS-Protection

1; mode=block

いいえ

クロス・サイト・スクリプティングの試みが検出されると、ページをブロックします。

ノート:

  • X-XSS-Protectionディレクティブは反射型XSS脆弱性の影響を軽減するための多層防御メカニズムであり、持続型またはDOMベースのXSS攻撃を検出またはブロックするものではありません。アプリケーションは、XSSに対する基本的な防御として、サーバーでの適切な入力検証と出力エンコーディングを依然として実行する必要があります。

  • Mozilla Firefoxは、クロス・サイト・スクリプティングからの保護を実装していません。

X-Permitted-Cross-Domain-Policies

none

いいえ

クロスドメイン・ポリシー・ファイルは、複数のドメインにまたがるデータを処理する権限をWebクライアントに付与するXMLドキュメントです。

X-Frame-Options

deny

いいえ

ブラウザでのクリックジャックを防止します。このディレクティブは、HTTPレスポンス・ヘッダーの使用によってのみ設定できます。同じオリジンからのコンテンツをフレーム化するには、sameoriginを使用します。既知のホストによりホストされている場合は、allow-frame hostnameを指定します。

ノート:

  • リクエストにCSPのframe-ancestorsおよびX-Frame-Optionsディレクティブの両方が含まれている場合、両方をサポートしているブラウザは、標準化されたCSPのframe-ancestorsディレクティブを優先し、X-Frame-Optionsディレクティブを無視します。

  • allow-frameディレクティブはワイルドカードをサポートしていません。

X-Content-Type-Options

nosniff

いいえ

ブラウザがMIMEタイプを使用してコンテンツ・タイプを決定するようにします。このディレクティブをイメージに使用するには、イメージ形式が指定されたMIMEタイプと一致することが必要です。このディレクティブをJavasSriptファイルに使用するには、MIMEタイプがtext/javascriptに設定されていることが必要です。

Strict-Transport-Security

max-age=<secs>; includeSubDomains

はい

HTTPSを介して指定されたサイト(および任意のサブドメイン)とのみ通信するようにブラウザに指示し、ユーザーが無効な証明書または自己署名証明書をオーバーライドしないようにします。

Referrer-Policy

no-referrer

いいえ

アウトバウンド・リンク・リクエストに関するリファラ情報を組み込むようにブラウザに指示します。

Public-Key-Pins

pin-sha256="<sha256>"; max-age=<secs>

はい

不完全または不正な証明書の使用を防止します。

Expect-CT

max-age=86400, enforce

はい

証明書透過性ポリシーの遵守が強制されている必要があることをブラウザに知らせます。

コンテンツ・セキュリティ・ポリシー・ヘッダー

コンテンツ・セキュリティ・ポリシー(CSP)はHTTPレスポンス・ヘッダーを介して提供され、Oracle JET Webアプリケーションが使用するリソースを制御します。

CSPヘッダーは、ブラウザで実行されるJavaScriptが必要なリソースをロードできる場所を制限し、JavaScriptの実行を制限し、ページをフレーム化できる状況を制御するメカニズムを提供します。これにより、クロス・サイト・スクリプティング(XSS)の脆弱性を軽減するとともにクリックジャック攻撃からの保護を提供できます。

ブラウザが実行可能スクリプト、スタイルシート、イメージ、フォントなどをロードするための有効なソースと見なす必要があるドメインを指定することにより、サーバー管理者が攻撃を軽減または排除するのに役立つようにブラウザに対してCSPを有効化する必要があります。CSPをサポートするブラウザのバージョンについては、ブラウザ互換性マトリックスを参照してください。

CSPを構成する際は、Content-Security-Policy HTTPヘッダーをWebページに追加し、ユーザー・エージェントがそのページにロードすることを許可されているリソースを制御するための値を指定します。WebページにContent-Security-Policy HTTPヘッダーを追加するには、Content-Security-Policy HTTPレスポンス・ヘッダーを返すようにWebサーバーを構成します。たとえば、基本的なCSPレスポンス・ヘッダーですが、ここでscript-srcディレクティブがリソース・タイプとして実行可能スクリプトを指定しており、'self'はブラウザがスクリプトをロードできる承認済ソースとして現行ドメインを指定している定数です。

Content-Security-Policy: script-src 'self'

CSPには、次に示すような一般的に使用される定数があります。

  • 'none': 特定のリソース・タイプの使用をブロックします。

  • 'self': 現行のオリジン(ただし、サブドメインを除く)に一致します。

  • 'unsafe-eval': eval()などのメカニズムの使用を許可します。

    unsafe-eval CSPドメインの代替として、JETには式エバリュエータが用意されており、これにより、JET式の構文を、安全でない評価を禁止するコンテンツ・セキュリティ・ポリシーに準拠した方法で評価できます。unsafe-evalドメインのデフォルトのCSP使用は変更されませんが、アプリケーションは、サポートされる式のタイプに関して、いくつかの制限を加えてJET動作を選択できます。CspExpressionEvaluator APIドキュメントで、作成、使用方法、サポートされる式および制限の詳細を参照してください。

または、HTMLメタ・タグを使用して、CSPを構成することもできます。たとえば:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; frame-src 'none';">

一部のCSPディレクティブ(たとえばframe-ancestors)は、HTMLメタ・タグを処理しないことに注意してください。

次の表は、JET機能を変更せずに最もセキュアなモードで実行されるJET Webアプリケーションで必要とされる即時利用可能な設定についての説明です。JET Webアプリケーションは、追加のリソース・オリジン用にこれらの設定を変更する必要がある場合があります。この表は、次の2つのシナリオに基づいてCSPを有効化する際に使用できる様々なレスポンス・ヘッダー・ディレクティブをリストしています。

  • 共通のホスト: JETとアプリケーションのソース・コードが同じサーバー上でホストされている場合

  • コンテンツ配信ネットワーク(CDN): JETコードはJET CDNから、アプリケーション・コードは別のサーバーからのものである場合

表15-2 Content-Security-Policyヘッダーのオプション

CSPのバージョン ヘッダーのオプション 共通のホスト CDN 説明

CSP 1.0

default-src

'none'

'none'

リソース・タイプが指定されていない場合、リソースのロードを確実にブロックするデフォルト設定として機能します。他のすべての設定は、特定のリソース・オリジンに対して明示的に有効化する必要があります。

CSP 1.0

connect-src

'self'

'self'

アクセス対象のRESTとWebソケットを管理します。

CSP 1.0

font-src

'self'

'self' static.oracle.com

フォントの有効なソースを指定します。

CSP 1.0

img-src

data: 'self'

'self' data: static.oracle.com

イメージの有効なソースを指定します。JETのインライン・イメージを許可します。

CSP 1.0

media-src

'none'

'none'

<audio><video><track>要素を使用して、メディアをロードする有効なソースを指定します。

CSP 1.0

object-src

'none'

'none'

<object><embed><applet>要素の有効なソースを指定します。

CSP 1.0

script-src

'self' 'unsafe-eval'

'self' static.oracle.com 'unsafe-eval';

JavaScriptの有効なソースを指定します。このディレクティブは、Knockout式およびJET機能の作成に使用されます。

ノート: 現在、式を解決するにはKnockoutでunsafe-evalを使用する必要がありますが、JETには、厳格なコンテンツ・セキュリティ・ポリシー環境でアプリケーションを実行する必要がある場合に別の式エバリュエータが用意されています。使用方法については、CspExpressionEvaluator APIドキュメントを参照してください。

CSP 1.0

sandbox

-

-

サンドボックス化されたiframe内でページを実行します。

CSP 2.0

form-action

-

-

このディレクティブはフォーム送信に使用されます。JETには適用できません。

CSP 2.0

frame-ancestors

'none'

'none'

<frame><iframe>などの要素を使用して、ネストされた参照コンテキストのロードについての有効なソースを指定し、ブラウザでのクリックジャックを防止します。このディレクティブは、HTTPレスポンス・ヘッダーの使用によってのみ設定できます。同じオリジンからのコンテンツをフレーム化するには、'self'を使用します。既知のホスト(1つまたは複数)によりホストされている場合、それらのホストを指定します。

default-srcnoneに設定されている場合、特定のリソース・オロジン用の他のすべての必要な設定を明示的に有効化する必要があります。

次の例は、Webサイト管理者が信頼できるドメインとそのすべてのサブドメインからのコンテンツを許可する場合のCSPの設定方法を示しています。

Content-Security-Policy: default-src 'self' *.trusted.com

次の例は、Webサイト管理者が、Webアプリケーションのユーザーがユーザーの持つコンテンツの任意のオリジンからのイメージを組み込むことを許可するが、オーディオまたはビデオ・メディアを信頼済のプロバイダに制限し、すべてのスクリプトを信頼済のコードをホストする特定のサーバーのみに制限する場合のCSPの設定方法を示しています。

Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

Oracle JETアプリケーションでのOAuthの使用

OAuthプラグインを使用して、クライアント(エンド・ユーザー)の個人データへのアクセスを管理できます。Oracle JET APIには、OAuthオブジェクトの初期化、初期化の検証、クライアント資格証明またはアクセス・トークンに基づく認可ヘッダーの計算に使用可能なメソッドを提供する、OAuthクラスが含まれています。

OAuthの初期化

OAuthコンストラクタを使用して、特定のOAuthオブジェクトのインスタンスを作成できます。

new OAuth(header, attributes)

attributesおよびheaderパラメータはオプションです。

パラメータ タイプ 説明

header

文字列

MIMEヘッダー名。デフォルトはAuthorizationです

attributes

オブジェクト

クライアント資格証明またはアクセス/Bearerトークンが含まれます。

クライアント資格証明には次が含まれます:

  • client_id (必須): 公開されているクライアント資格証明

  • client_secret (必須): 秘密のクライアント資格証明

  • bearer_url (必須): Bearerのトークンおよび資格証明のリフレッシュ用URL

  • 追加の属性(必要な場合)(オプション)

アクセス/Bearerトークンには次が含まれます。

  • access_token (必須): Bearerトークン

  • 追加の属性(必要な場合)(オプション)

次のコード・サンプルは、OAuthを初期化する3つの例を示しています。

// Initialize OAuth with client credentials
var myOAuth = new OAuth('X-Header', {...Client credentials...});

// Initialize OAuth with token credentials
var myOAuth = new OAuth('X-Header', {...Access/Bearer token...});

// Initialize OAuth manually
var myOAuth = new OAuth();

OAuthを手動で初期化する場合は、次のコード・サンプルに示すメソッドを使用して、クライアント資格証明またはアクセス/Bearerトークンを追加できます。

// Initializing client credentials manually
myOAuth.setAccessTokenRequest({...Client Credentials ...});
myOAuth.clientCredentialGrant();

// Initializing access bearer token manually
myOAuth.setAccessTokenResponse({...Access Token...});

OAuth APIには、クライアント資格証明またはアクセス・トークンを取得および消去するためのメソッドも含まれています。詳細は、OAuth APIドキュメントを参照してください。

OAuth初期化の検証

isInitialized()メソッドを使用して、初期化が成功したことを検証します。

var initFlag = myOAuth.isInitialized();

OAuthヘッダーの取得

getHeader()メソッドを使用して、OAuthヘッダーを取得します。メソッドでは、クライアント資格証明またはアクセス・トークンに基づいて認可ヘッダーを計算します。

// Client credentials
var myOAuth = new OAuth('New-Header', {...Client credentials...});
var myHeaders =  myOAuth.getHeader();

// Access token
var myOAuth = new OAuth('New-Header', {...Access/Bearer token...});
var myHeaders =  myOAuth.getHeader();

// Manual initialization, client credentials
var myOAuth = new OAuth();
myOAuth.setAccessTokenRequest({...Client credentials...});
var myHeaders =  myOAuth.getHeader();

// Manual initialization, access token
var myOAuth = new OAuth('New-Header', {...Access/Bearer token...});
var myHeaders =  myOAuth.getHeader();

Cross-Origin Resource Sharing (CORS)について

CORSとは、Webページ上の制限されたリソースを、最初にリソースが提供されたドメインの外部にある別のドメインからリクエストできるようにするメカニズムです。デフォルトでは、JavaScriptの同一生成元セキュリティ・ポリシーにより、Ajaxリクエストなどの特定のクロス・ドメイン・リクエストが禁止されます。

CORSによってリソース・リクエストが拒否されることが、Webアプリケーションに影響を及ぼす可能性があります。拒否が発生すると、アプリケーションは、リソース・リクエストに応じて、次の例のようなメッセージを受信します:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

サーバー側の管理者は、信頼されるクライアントからのクロスサイト・リクエストを許可するようにリモート・サーバーで使用されるポリシーを変更することにより、それらのリソースへのアクセスが許可された生成元を指定できます。たとえば、Oracle Mobile Cloud Service (MCS)で管理されるリモート・サービスにアクセスするには、MCS管理者が、異なるドメインからのリソースを提供するリモート・サービスを識別するURLパターンのカンマ区切りリストを使用して、MCSのSecurity_AllowOrigin環境ポリシーを構成します。

テスト目的でローカル・ブラウザにWebアプリケーションを提供する場合、CORSによって拒否される可能性があります。ブラウザによっては、Chromeの--disable-web-securityやFirefoxのsecurity.fileuri.strict_origin_policyなど、CORSを無効にするオプションが用意されていたり、CORSを回避するプラグインがサポートされている場合もあります。

これらのオプションはアプリケーションをテストするときにのみ使用し、本番環境でアプリケーションにCORSの問題が発生しないことを確認するために、必ず、本番と同様の環境で、これらのオプションを使用しないで、さらにテストしてください。