Azure Functions のセキュリティ保護
サーバーレス関数の安全な開発、デプロイ、操作のための計画は、多くの点において Web ベースやクラウドホステッド アプリケーションのためのものと非常に似ています。 Azure App Service には、関数アプリ向けのホスティング インフラストラクチャが用意されています。 この記事では、関数コードを実行する場合のセキュリティ戦略と、App Service を利用して関数をセキュリティで保護する方法について説明します。
Azure VM、ストレージ、ネットワーク接続、Web フレームワーク、管理、統合機能を含む App Service のプラットフォーム コンポーネントは、積極的に保護され、強化されています。 App Service は、徹底したコンプライアンス チェックを継続的に行い、以下の点を確認しています。
- お客様のアプリのリソースが、他のお客様の Azure リソースからセキュリティで保護されていること。
- 新たに発見された脆弱性に対応できるように、VM インスタンスとランタイム ソフトウェアが定期的に更新されていること。
- アプリと他の Azure リソース (SQL Database など) 間のシークレット (接続文字列など) の通信が Azure 内にとどまり、ネットワーク境界を越えないこと。 保存時にシークレットが常に暗号化されていること。
- ハイブリッド接続などの App Service 接続機能を介したすべての通信が暗号化されていること。
- Azure PowerShell、Azure CLI、Azure SDK、REST API などのリモート管理ツールとの接続がすべて暗号化されていること。
- 24 時間体制の脅威管理によって、マルウェア、分散型サービス拒否 (DDoS)、man-in-the-middle (MITM) などの脅威からインフラストラクチャとプラットフォームが保護されていること。
Azure のインフラストラクチャとプラットフォームのセキュリティの詳細については、 Azure セキュリティ センターを参照してください。
Microsoft クラウド セキュリティ ベンチマークに準拠した一連のセキュリティ推奨事項については、「Azure Functions 用の Azure セキュリティ ベースライン」を参照してください。
操作をセキュリティで保護する
このセクションでは、関数アプリの構成および実行を可能な限り安全に行う方法について説明します。
Defender for Cloud
ポータルでは、Defender for Cloud が関数アプリと統合されます。 これにより、構成に関連する潜在的なセキュリティ脆弱性を、無料ですばやく評価することができます。 専用プランで実行されている関数アプリでは、追加のコストを支払うことで Defender for Cloud の強化されたセキュリティ機能も使用できます。 詳細については、「Azure App Service Web アプリと API を保護する」を参照してください。
ログ記録と監視を行う
攻撃を検出する方法の 1 つが、アクティビティの監視とログ分析を利用することです。 Functions は Application Insights と統合されており、関数アプリのログ、パフォーマンス、エラー データが収集されます。 Application Insights はパフォーマンスの異常を自動的に検出するほか、問題の診断や、関数の使用状況の把握に役立つ強力な分析ツールを備えています。 詳細については、「Azure Functions を監視する」を参照してください。
Functions は Azure Monitor のログとも統合されており、関数アプリのログをシステム イベントと統合して分析を容易に進めることができます。 診断設定を使用すると、選択した送信先 (Logs Analytics ワークスペースなど) に対する関数のプラットフォーム ログおよびメトリックのストリーミング エクスポートを構成できます。 詳細については、「Azure Monitor ログを使用した Azure Functions の監視」を参照してください。
エンタープライズレベルで脅威検出と対応を自動化するには、Logs Analytics ワークスペースにログとイベントをストリーム配信します。 その後、このワークスペースに Azure Sentinel を接続できます。 詳細については、Microsoft Sentinel の概要ページを参照してください。
監視に関するその他のセキュリティ推奨事項については、「Azure Functions 用の Azure セキュリティ ベースライン」を参照してください。
HTTP エンドポイントをセキュリティで保護する
一般に公開されている HTTP エンドポイントは、悪意のあるアクターにとっての攻撃のベクトルを提供します。 HTTP エンドポイントをセキュリティで保護する際には、階層的なセキュリティのアプローチを使用する必要があります。 以下に示す手法を使用すると、一般に公開されている HTTP エンドポイントの脆弱性を軽減できます。これらは、最も基本的なものから最も安全で制約の強いものの順に並んでいます。
- HTTPS を要求する
- アクセス キーを要求する
- App Service 認証/認可を有効にする
- Azure API Management (APIM) を使用して要求を認証する
- 関数アプリを仮想ネットワークに展開する
- 関数アプリを分離してデプロイする
HTTPS を必須にする
既定では、クライアントは HTTP または HTTPS のどちらかで関数のエンドポイントに接続できます。 HTTPS では、SSL/TLS プロトコルによりセキュリティで保護された接続 (暗号化と認証の両方が実施されたもの) が実現できるため、HTTP を HTTPS にリダイレクトしてください。 方法については、「HTTPS の適用」を参照してください。
HTTPS を要求する場合は、最新の TLS バージョンも要求する必要があります。 方法については、「TLS バージョンを適用する」を参照してください。
詳細については、安全な接続 (TLS) に関するページを参照してください。
関数のアクセス キー
Functions では、関数エンドポイントへのアクセスをより困難にするためのキーを使用することができます。 HTTP トリガー関数での HTTP アクセス レベルが anonymous
に設定されている場合を除き、要求は内部にアクセス キーを含んでいる必要があります。 詳細については、「Azure Functions でのアクセス キーの使用」を参照してください。
アクセス キーによって望ましくないアクセスをある程度軽減することはできますが、関数エンドポイントを本当の意味で保護する唯一の方法は関数にアクセスするクライアントのポジティブ認証を実装することです。 そのうえで、ID に基づいて承認の判断を行えます。
最高レベルのセキュリティを確保するために、プライベート エンドポイントの使用または分離状態での実行によって仮想ネットワーク内のアプリケーション アーキテクチャ全体をセキュリティで保護することもできます。
管理エンドポイントを無効にする
関数アプリは、ホスト状態情報の取得やテスト呼び出しの実行などの操作に使用できる、/admin
ルートの下にある管理エンドポイントを提供できます。 公開された場合、これらのエンドポイントに対する要求には、アプリのマスター キーが含まれている必要があります。 管理操作は、Azure RBAC を提供する Azure Resource Manager Microsoft.Web/sites
API を介しても使用可能です。 functionsRuntimeAdminIsolationEnabled
サイト プロパティを true
に設定することで、/admin
エンドポイントを無効にできます。 このプロパティは、Linux 従量課金プラン SKU で実行されているアプリには設定できません。また、Azure Functions のバージョン 1.x で実行されているアプリにも設定できません。 バージョン 1.x を使用している場合は、最初にバージョン 4.x に移行する必要があります。
App Service の認証/承認の有効化
App Service プラットフォームでは、Microsoft Entra ID といくつかのサードパーティ ID プロバイダーを使用してクライアントを認証することができます。 この方法を使用して、関数のカスタム承認ルールを実装し、関数コードのユーザー情報を操作できます。 詳細については、「Azure App Service での認証および承認」および「クライアント ID の操作」を参照してください。
Azure API Management (APIM) を使用して要求を認証する
APIM は、受信要求に対するさまざまな API セキュリティ オプションを提供します。 詳細については、 「Azure Functions で接続を管理する方法」を参照してください。 APIM を適切に配置すると、APIM インスタンスの IP アドレスからの要求のみを受け入れるように関数アプリを設定できます。 詳細については、IP アドレス制限を参照してください。
アクセス許可
他のアプリケーションやサービスと同じく、可能な限り低いアクセス許可で関数アプリを実行することを目標とします。
ユーザー管理のアクセス許可
関数では、組み込みの Azure のロールベースのアクセス制御 (Azure RBAC) がサポートされます。 関数でサポートされる Azure ロールは、共同作成者、所有者、および閲覧者です。
アクセス許可は、関数アプリ レベルで有効です。 ほとんどの関数アプリレベルのタスクを実行するには、共同作成者ロールが必要です。 Application Insights でログ データを表示できるようにするには、監視閲覧者のアクセス許可と共に共同作成者ロールも必要です。 関数アプリの削除は、所有者ロールでのみ行えます。
関数を権限別に整理する
アプリケーションの設定に格納されている接続文字列やそれ以外の資格情報では、関数アプリに含まれるすべての関数に対して、関連リソース内で同一のアクセス許可セットが付与されます。 こうした資格情報を使用しない関数は別の関数アプリに移動して、特定の資格情報にアクセスできる関数の数を最小限に抑えることを検討してください。 異なる関数アプリの関数間でのデータの受け渡しは、関数チェーンなどの手法を使用すればいつでも行えます。
マネージド ID
Microsoft Entra ID のマネージド ID を使用すると、アプリは他の Microsoft Entra で保護されたリソース (Azure Key Vault など) に簡単にアクセスできます。 ID は Azure プラットフォームによって管理され、ユーザーがシークレットをプロビジョニングまたはローテーションする必要はありません。 Microsoft Entra ID のマネージド ID の詳細については、「Azure リソースのマネージド ID」を参照してください。
アプリケーションには 2 種類の ID を付与できます。
- システム割り当て ID はアプリに関連付けられ、そのアプリが削除されると削除されます。 アプリは 1 つのシステム割り当て ID しか持つことはできません。
- ユーザー割り当て ID は、アプリに割り当てることができるスタンドアロン Azure リソースです。 1 つのアプリは複数のユーザー割り当て ID を持つことができ、1 つのユーザー割り当て ID は複数の Azure リソース (2 つの App Service アプリなど) に割り当てることができます。
マネージド ID は、一部のトリガーとバインドから接続するために、シークレットの代わりに使用できます。 「ID ベースの接続」を参照してください。
詳細については、「App Service と Azure Functions でマネージド ID を使用する方法」を参照してください。
CORS アクセスを制限する
クロスオリジン リソース共有 (CORS) を利用すると、別のドメインで実行されている Web アプリから HTTP トリガー エンドポイントに対して要求を行うことができます。 App Service には、HTTP 要求で必須の CORS ヘッダーを渡すサポート機能が組み込まれています。 CORS のルールは、関数アプリ レベルで定義されます。
すべてのサイトにエンドポイントへのアクセスを許可するワイルドカードを使いたくなりますが、クロスサイト スクリプティング攻撃を防止するという CORS の目的が損なわれます。 代わりに、エンドポイントへのアクセスが必要な各 Web アプリのドメイン用に、個別の CORS エントリを追加してください。
シークレットを管理する
関数アプリで、コードの実行に必要な各種サービスやリソースに接続するには、接続文字列やサービス キーなどのシークレットにアクセスできる必要があります。 このセクションでは、関数に必要なシークレットを格納する方法について説明します。
関数コード内にはシークレットを格納しないでください。
アプリケーションの設定
既定では、関数アプリとバインディングで使用する接続文字列およびシークレットは、アプリケーション設定として格納します。 こうすると、関数コード、および関数で使用するさまざまなバインディングの両方で、これらの資格情報を利用できます。 実際の値 (シークレット) を取得するには、アプリケーション設定 (キー) の名前を使用します。
たとえば、すべての関数アプリには、ランタイムで使用される関連ストレージ アカウントが必要です。 既定では、このストレージ アカウントへの接続は、AzureWebJobsStorage
という名前のアプリケーション設定に格納されます。
アプリ設定と接続文字列は、Azure で暗号化されて格納されます。 これらの暗号化は、アプリの起動時にアプリのプロセス メモリに挿入される前にのみ解除されます。 暗号化キーは定期的にローテーションされます。 セキュリティで保護されたシークレットのストレージを自分で管理するには、代わりに、アプリ設定で Azure Key Vault のシークレットを参照する必要があります。
ローカル コンピューターで関数を開発するときに、local.settings.json
ファイルで既定で設定を暗号化することもできます。 詳細については、ローカル設定ファイルの暗号化に関する記事を参照してください。
Key Vault の参照
ほとんどの関数ではアプリケーション設定で十分ですが、複数サービスにわたって同一のシークレットを共有する必要がある場合もあります。 この場合、シークレットのストレージが余分にあると、潜在的な脆弱性が高まります。 より安全な方法としては、一元的なシークレット ストレージ サービスを利用し、シークレット自体ではなくこのサービスを参照します。
Azure Key Vault は、アクセス ポリシーと監査履歴を完全制御する、一元化されたシークレット管理を提供するサービスです。 アプリケーション設定の接続文字列またはキーの代わりに、Key Vault 参照を使用できます。 詳細については、「App Service と Azure Functions の Key Vault 参照を使用する」を参照してください。
ID ベースの接続
一部のリソースに接続するために、シークレットの代わりに ID を使用できます。 これには、シークレットの管理を必要としないという利点があり、よりきめ細かなアクセスの制御と監査が提供されます。
Microsoft Entra 認証をサポートしている Azure サービスへの接続を作成するコードを記述する際には、シークレットや接続文字列の代わりに ID を使用することを選択できます。 両方の接続方法の詳細については、各サービスのドキュメントを参照してください。
一部の Azure Functions バインド拡張機能は、ID ベースの接続を使用してサービスにアクセスするように構成できます。 詳細については、「ID ベースの接続の構成」を参照してください。
使用量クォータを設定する
従量課金プランで実行する関数については、使用量クォータを設定することを検討してください。 関数アプリの関数の合計実行回数に対して日次 GB 秒の制限を設定すると、この制限に達したときに実行が停止されます。 これによって、悪意のあるコードによる関数の実行を抑えられる可能性があります。 関数のコストを見積もる方法については、「従量課金プランのコストの見積もり」を参照してください。
データ検証
関数で使用するトリガーとバインドでは、追加のデータ検証は行われません。 トリガーまたは入力バインドから受け取るデータはすべて、コードで検証する必要があります。 アップストリーム サービスが侵害された場合、未検証の入力が関数に渡されないようにする必要があります。 たとえば、リレーショナル データベースの Azure Storage キューからのデータを関数に格納するのであれば、SQL インジェクション攻撃を防ぐために、データを検証し、コマンドをパラメーター化する必要があります。
関数に送信されるデータが既に検証またはサニタイズ済みであると思わないでください。 また、出力バインドに書き込まれるデータが妥当であるか検証することもお勧めします。
エラーを処理する
基本的なことですが、関数に適切なエラー処理を記述することが重要です。 未処理のエラーはホストにまで伝播し、ランタイムによって処理されます。 バインドによって、エラーの処理は異なります。 詳細については、「Azure Functions のエラー処理」を参照してください。
リモート デバッグの無効化
関数のデバッグを積極的に行う場合を除き、リモート デバッグは無効にしてください。 リモート デバッグは、ポータルの関数アプリの [構成] の [全般設定] タブで無効にできます。
CORS アクセスを制限する
Azure Functions では、クロス オリジン リソース共有 (CORS) がサポートされています。 CORS はポータル内で、Azure CLI によって構成されます。 CORS の許可配信元一覧は、関数アプリ レベルで適用されます。 CORS を有効にすると、応答に Access-Control-Allow-Origin
ヘッダーが含まれます。 詳細については、「 クロス オリジン リソース共有」を参照してください。
許可されるオリジンの一覧でワイルドカードを使用しないでください。 代わりに、要求の取得元になる特定のドメインを記載してください。
暗号化したデータを格納する
Azure Storage は、保存されているストレージ アカウント内のすべてのデータを暗号化します。 詳細については、「保存データ向け Azure ストレージの暗号化」をご覧ください。
規定では、データは Microsoft のマネージド キーで暗号化されます。 暗号化キーをさらに制御するために、BLOB とファイル データの暗号化に使用する目的で、顧客が管理するキーを提供できます。 Functions からストレージ アカウントにアクセスできるように、これらのキーは Azure Key Vault 内に置かれている必要があります。 詳細については、「カスタマー マネージド キーを使用した保存時の暗号化」をご覧ください。
関連リソースをセキュリティで保護する
関数アプリは多くの場合、追加のリソースに依存するため、アプリをセキュリティで保護することには、これらの外部リソースをセキュリティで保護することも含まれます。 少なくとも、ほとんどの関数アプリには、Application Insights と Azure Storage への依存関係が含まれています。 これらのリソースを保護するためのガイダンスについては、Azure Monitor の Azure セキュリティ ベースラインと Storage 用の Azure セキュリティ ベースラインを参照してください。
重要
ストレージ アカウントは、アプリケーション コード自体を含む重要なアプリ データを格納するために使用されます。 他のアプリやユーザーからのアクセスをストレージ アカウントに制限する必要があります。
また、アプリケーション ロジックが依存するリソースの種類については、トリガーとバインドの両方として、および関数コードからのガイダンスを参照する必要があります。
セキュリティで保護されたデプロイ
Azure Functions のツーリング統合機能により、Azure にローカルの関数プロジェクト コードを容易に発行できます。 Azure Functions トポロジのセキュリティについて検討する場合、デプロイのしくみを理解することが重要です。
デプロイ資格情報
App Service をデプロイするには、一連のデプロイ資格情報が必要です。 これらの資格情報は、関数アプリのデプロイを保護するために使用されます。 デプロイ資格情報は App Service プラットフォームにより管理され、保存時に暗号化されます。
デプロイ資格情報には次の 2 種類があります。
ユーザー レベルの資格情報: Azure アカウント全体の資格情報セットです。 これを使用して、Azure アカウントがアクセス許可を持っているすべてのアプリをサブスクリプションに関係なく App Service にデプロイできます。 これは、ポータルの GUI (アプリのリソース ページの [概要] や [プロパティ] など) に表示される既定のセットです。 ユーザーがロールベースのアクセス制御 (RBAC) または共同管理者のアクセス許可を使用してアプリのアクセス権を付与されると、そのユーザーは、アクセス権が取り消されるまで自分のユーザーレベル資格情報を使用できます。 これらの資格情報は他の Azure ユーザーと共有しないでください。
アプリ レベルの資格情報: アプリごとの資格情報セットです。 そのアプリのみにデプロイするために使用できます。 各アプリの資格情報は、アプリの作成時に自動的に生成されます。 これらは手動で構成できませんが、いつでもリセットできます。 RBAC を使用してアプリ レベルの資格情報へのアクセス権がユーザーに付与される場合、そのユーザーはアプリに対して共同作成者以上の権限 (Web サイトの共同作成者の組み込みロールを含む) を持つ必要があります。 閲覧者は発行を許可されていないため、この資格情報にアクセスできません。
現時点では、デプロイ資格情報では Key Vault はサポートされていません。 デプロイ資格情報の管理の詳細については、「Azure App Service のデプロイ資格情報の構成」を参照してください。
FTP を無効にする
既定では、関数アプリごとに FTP エンドポイントが有効になります。 FTP エンドポイントには、デプロイ資格情報を使用してアクセスします。
関数コードをデプロイする場合、FTP は推奨されません。 FTP デプロイは手動であり、実行するにはトリガーを同期する必要があります。 詳細については、FTP デプロイに関するページを参照してください。
FTP を使用する予定がない場合は、ポータルで無効にしてください。 FTP を使用する場合は、FTPS を強制してください。
scm
エンドポイントを保護する
各アプリには対応する scm
サービス エンドポイントがあり、これらのエンドポイントは、Advanced Tools (Kudu) サービスがデプロイに使用したり、他の App Service のサイト拡張機能に使用したりします。 関数アプリの scm
エンドポイントは、常に https://<FUNCTION_APP_NAME>.scm.azurewebsites.net
という形式の URL になります。 ネットワークの分離を使用して関数を保護する場合は、このエンドポイントについても考慮する必要があります。
scm
エンドポイントを個別に用意することで、隔離されているか、仮想ネットワーク内で実行されている他の関数アプリに関して、デプロイやその他の Advanced Tools の機能を制御できます。 scm
エンドポイントでは、(デプロイ資格情報を使用した) 認証および Azure portal 資格情報を使用したシングル サインオンの両方がサポートされます。 詳細については、「Kudu サービスへのアクセス」を参照してください。
継続的なセキュリティ検証
セキュリティについては開発プロセスのあらゆる段階で検討する必要があるので、継続的デプロイ環境でセキュリティ検証を実装することもお勧めします。 これは、DevSecOps とも呼ばれます。 デプロイ パイプラインに Azure DevOps を使用すると、デプロイ プロセスに検証を統合できます。 詳細については、「CI/CD パイプラインに継続的なセキュリティ検証を追加する方法」を参照してください。
ネットワークのセキュリティ
関数アプリに対するネットワーク アクセスを制限することで、関数エンドポイントにアクセス可能なユーザーを制御できます。 Functions では App Service インフラストラクチャを利用しており、インターネットのルーティング可能なアドレスを使用したり、関数エンドポイントへのインターネット アクセスを制限したりすることなく、関数からリソースにアクセスできます。 これらのネットワーク オプションの詳細については、「Azure Functions のネットワーク オプション」を参照してください。
アクセス制限を設定する
アクセス制限を使用すると、許可規則および拒否規則の一覧を定義して、アプリへのトラフィックを制御できます。 規則は、優先度に従って評価されます。 ルールが定義されていない場合、アプリは任意のアドレスからのトラフィックを受け入れます。 詳細については、「Azure App Service のアクセス制限」を参照してください。
ストレージ アカウントをセキュリティで保護する
関数アプリを作成するときは、BLOB、Queue、および Table Storage をサポートする汎用の Azure Storage アカウントを作成またはリンクする必要があります。 このストレージ アカウントは、サービス エンドポイントまたはプライベート エンドポイントによるアクセスが有効な仮想ネットワークによってセキュリティ保護されているストレージ アカウントに置き換えることができます。 詳細については、「ストレージ アカウントを仮想ネットワークに制限する」を参照してください。
関数アプリを仮想ネットワークにデプロイする
Azure プライベート エンドポイントは、Azure Private Link を使用するサービスに、プライベートで安全に接続するためのネットワーク インターフェイスです。 プライベート エンドポイントでは、仮想ネットワークのプライベート IP アドレスを使用して、サービスが仮想ネットワークに実質的に組み込まれます。
Flex 従量課金、エラスティック Premium、専用 (App Service) の各プランでホストされている機能にプライベート エンドポイントを使用できます。
プライベート エンドポイントを呼び出す場合は、DNS 参照がプライベート エンドポイントに解決されるようにする必要があります。 この動作は、次のいずれかの方法で実現できます。
- Azure DNS プライベート ゾーンと統合する。 仮想ネットワークにカスタム DNS サーバーがない場合、これは自動的に行われます。
- アプリで使用される DNS サーバーでプライベート エンドポイントを管理する。 プライベート エンドポイントを管理するには、エンドポイント アドレスを把握し、A レコードを使用して、到達しようとしているエンドポイントを参照する必要があります。
- Azure DNS プライベート ゾーンに転送する独自の DNS サーバーを構成する。
詳細については、Web Apps でのプライベート エンドポイントの使用に関する記事を参照してください。
関数アプリを分離してデプロイする
Azure App Service Environment は、内部で関数を実行するための専用のホスティング環境を提供します。 これらの環境では、すべての受信要求の認証に使用できる単一のフロントエンド ゲートウェイを構成できます。 詳細情報については、App Service 環境の Web アプリケーション ファイアウォール (WAF) を構成するを参照してください。
ゲートウェイ サービスを使用する
Azure Application Gateway や Azure Front Door などのゲートウェイ サービスを使用すると、Web アプリケーション ファイアウォール (WAF) を設定できます。 WAF 規則は検出された攻撃の監視またはブロックに使用され、関数の保護のための新しい層になります。 WAF を設定するには、関数アプリを ASE 内で実行するか、プライベート エンドポイント (プレビュー) を使用して実行する必要があります。 詳細については、プライベート エンドポイントの使用に関するページを参照してください。