接続文字列とその他の構成情報を保護する (C#)
ASP.NET アプリケーションは、通常、Web.config ファイルに構成情報を格納します。 この情報の一部は機密性が高く、保護を保証します。 既定では、このファイルは Web サイトの訪問者には提供されませんが、管理者またはハッカーが Web サーバーのファイル システムにアクセスし、ファイルの内容を表示する場合があります。 このチュートリアルでは、ASP.NET 2.0 を使用すると、Web.config ファイルのセクションを暗号化して機密情報を保護できます。
はじめに
ASP.NET アプリケーションの構成情報は、一般的に という名前 Web.config
の XML ファイルに格納されます。 これらのチュートリアルの過程で、いくつかの時間を Web.config
更新しました。 たとえば、最初のNorthwind
チュートリアルで型指定された DataSet を作成すると、接続文字列情報は セクションの に<connectionStrings>
自動的にWeb.config
追加されました。 後で、マスター ページとサイト ナビゲーションのチュートリアルで、 を手動で更新Web.config
し、プロジェクト内のすべての ASP.NET ページでテーマを使用する必要があることを示す要素をDataWebControls
追加<pages>
しました。
接続文字列などの機密データが含まれている可能性があるため Web.config
、 の内容を安全に保ち、未承認の Web.config
閲覧者から非表示にすることが重要です。 既定では、拡張子を持つ .config
ファイルに対する HTTP 要求は、ASP.NET エンジンによって処理されます。 この種類のページは 、図 1 に示すメッセージを提供しません。 つまり、訪問者はブラウザーのアドレス バーに入力http://www.YourServer.com/Web.configするだけでは、ファイルの内容を表示Web.config
できません。
図 1: ブラウザーから Web.config
アクセスすると、この種類のページが返されます。メッセージは表示されません (フルサイズの画像を表示する 場合はクリックします)
しかし、攻撃者がファイルの内容を表示 Web.config
できる他の悪用を見つけた場合はどうでしょうか。 攻撃者はこの情報に対して何を行う可能性があり、 内 Web.config
の機密情報をさらに保護するためにどのような手順を実行できますか? 幸いなことに、 のほとんどのセクションには Web.config
機密情報が含まれていません。 ASP.NET ページで使用されている既定のテーマの名前がわかっている場合、攻撃者はどのような害を及ぼす可能性がありますか?
ただし、特定 Web.config
のセクションには、接続文字列、ユーザー名、パスワード、サーバー名、暗号化キーなどの機密情報が含まれています。 この情報は、通常、次 Web.config
のセクションで確認できます。
<appSettings>
<connectionStrings>
<identity>
<sessionState>
このチュートリアルでは、このような機密性の高い構成情報を保護するための手法について説明します。 ご覧のように、.NET Framework バージョン 2.0 には、選択した構成セクションをプログラムで暗号化および復号化する保護された構成システムが含まれています。
注意
このチュートリアルでは、ASP.NET アプリケーションからデータベースに接続するための Microsoft の推奨事項について説明します。 接続文字列の暗号化に加えて、セキュリティで保護された方法でデータベースに接続していることを確認することで、システムのセキュリティ強化に役立ちます。
手順 1: ASP.NET 2.0 s の保護された構成オプションの確認
ASP.NET 2.0 には、構成情報を暗号化および復号化するための保護された構成システムが含まれています。 これには、構成情報をプログラムで暗号化または復号化するために使用できる.NET Frameworkのメソッドが含まれます。 保護された構成システムでは、プロバイダー モデルを使用します。これにより、開発者は、使用される暗号化実装を選択できます。
.NET Frameworkには、次の 2 つの保護された構成プロバイダーが付属しています。
RSAProtectedConfigurationProvider
- 暗号化と暗号化解除に非対称 RSA アルゴリズム を使用します。DPAPIProtectedConfigurationProvider
- 暗号化と暗号化解除に Windows Data Protection API (DPAPI) を使用します。
保護された構成システムはプロバイダー設計パターンを実装するため、独自の保護された構成プロバイダーを作成してアプリケーションにプラグインすることができます。 このプロセスの詳細については、「 保護された構成プロバイダーの実装 」を参照してください。
RSA プロバイダーと DPAPI プロバイダーは、暗号化および暗号化解除ルーチンにキーを使用します。これらのキーは、マシン レベルまたはユーザー レベルで格納できます。 マシン レベルのキーは、Web アプリケーションが専用サーバー上で実行されるシナリオや、暗号化された情報を共有する必要がある複数のアプリケーションがサーバー上にある場合に最適です。 ユーザー レベルのキーは、同じサーバー上の他のアプリケーションがアプリケーションの保護された構成セクションを復号化できないようにする共有ホスティング環境では、より安全なオプションです。
このチュートリアルでは、DPAPI プロバイダーとマシン レベルのキーを使用する例を示します。 具体的には、 のWeb.config
セクションの<connectionStrings>
暗号化について説明しますが、保護された構成システムを使用してほとんどのWeb.config
セクションを暗号化できます。 ユーザー レベルのキーの使用または RSA プロバイダーの使用については、このチュートリアルの最後にある「その他の読み取り」セクションのリソースを参照してください。
注意
RSAProtectedConfigurationProvider
プロバイダーと DPAPIProtectedConfigurationProvider
プロバイダーはそれぞれ、プロバイダー名RsaProtectedConfigurationProvider
と DataProtectionConfigurationProvider
を使用してファイルに登録されますmachine.config
。 構成情報を暗号化または暗号化解除する場合は、実際の型名 ( と DPAPIProtectedConfigurationProvider
) ではなく、適切なプロバイダー名 (RsaProtectedConfigurationProvider
RSAProtectedConfigurationProvider
または DataProtectionConfigurationProvider
) を指定する必要があります。 フォルダー内の machine.config
ファイルを $WINDOWS$\Microsoft.NET\Framework\version\CONFIG
見つけることができます。
手順 2: 構成セクションのプログラムによる暗号化と暗号化解除
数行のコードを使用すると、指定したプロバイダーを使用して特定の構成セクションを暗号化または暗号化解除できます。 このコードは、簡単に説明しますが、プログラムで適切な構成セクションを参照し、その または UnprotectSection
メソッドをProtectSection
呼び出してから、 メソッドをSave
呼び出して変更を保持する必要があります。 さらに、.NET Frameworkには、構成情報を暗号化および復号化できる便利なコマンド ライン ユーティリティが含まれています。 このコマンド ライン ユーティリティは、手順 3 で確認します。
構成情報をプログラムで保護する方法を説明するために、 で セクションWeb.config
を暗号化および暗号化解除するためのボタンを含む ASP.NET ページを<connectionStrings>
作成しましょう。
まず、フォルダー内の EncryptingConfigSections.aspx
ページを AdvancedDAL
開きます。 ツールボックスから Designerに TextBox コントロールをドラッグし、そのプロパティを ID
に、そのTextMode
プロパティを WebConfigContents
にMultiLine
、プロパティWidth
Rows
をそれぞれ 95% と 15 に設定します。 この TextBox コントロールには、 の Web.config
内容が表示され、コンテンツが暗号化されているかどうかをすぐに確認できます。 もちろん、実際のアプリケーションでは、 の Web.config
内容を表示する必要はありません。
TextBox の下に、 と DecryptConnStrings
という名前EncryptConnStrings
の 2 つの Button コントロールを追加します。 [テキスト] プロパティを [接続文字列の暗号化] と [接続文字列の暗号化解除] に設定します。
この時点で、画面は図 2 のようになります。
図 2: TextBox コントロールと 2 つのボタン Web コントロールをページに追加する (クリックするとフルサイズの画像が表示されます)
次に、ページが最初に読み込まれるときに TextBox に の Web.config
内容を WebConfigContents
読み込んで表示するコードを記述する必要があります。 次のコードをページの分離コード クラスに追加します。 このコードは、 という名前DisplayWebConfig
のメソッドを追加し、 が false
の場合Page.IsPostBack
にPage_Load
イベント ハンドラーから呼び出します。
protected void Page_Load(object sender, EventArgs e)
{
// On the first page visit, call DisplayWebConfig method
if (!Page.IsPostBack)
DisplayWebConfig();
}
private void DisplayWebConfig()
{
// Reads in the contents of Web.config and displays them in the TextBox
StreamReader webConfigStream =
File.OpenText(Path.Combine(Request.PhysicalApplicationPath, "Web.config"));
string configContents = webConfigStream.ReadToEnd();
webConfigStream.Close();
WebConfigContents.Text = configContents;
}
メソッドではDisplayWebConfig
、 クラスをFile
使用してアプリケーションのWeb.config
ファイルを開き、StreamReader
クラスを使用してその内容を文字列に読み取り、クラスをPath
使用してファイルへの物理パスをWeb.config
生成します。 これら 3 つのクラスはすべて 名前空間にありますSystem.IO
。 そのため、分離コード クラスの先頭に ステートメントを追加するか、またはこれらのクラス名の前に を付 using
System.IO
ける System.IO.
必要があります。
次に、2 つの Button コントロール Click
イベントのイベント ハンドラーを追加し、DPAPI プロバイダーでマシン レベルのキーを使用してセクションを暗号化および暗号化解除 <connectionStrings>
するために必要なコードを追加する必要があります。 Designerから、各 Buttons をダブルクリックして分離コード クラスにイベント ハンドラーを追加Click
し、次のコードを追加します。
protected void EncryptConnStrings_Click(object sender, EventArgs e)
{
// Get configuration information about Web.config
Configuration config =
WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
// Let's work with the <connectionStrings> section
ConfigurationSection connectionStrings = config.GetSection("connectionStrings");
if (connectionStrings != null)
// Only encrypt the section if it is not already protected
if (!connectionStrings.SectionInformation.IsProtected)
{
// Encrypt the <connectionStrings> section using the
// DataProtectionConfigurationProvider provider
connectionStrings.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
config.Save();
// Refresh the Web.config display
DisplayWebConfig();
}
}
protected void DecryptConnStrings_Click(object sender, EventArgs e)
{
// Get configuration information about Web.config
Configuration config =
WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
// Let's work with the <connectionStrings> section
ConfigurationSection connectionStrings =
config.GetSection("connectionStrings");
if (connectionStrings != null)
// Only decrypt the section if it is protected
if (connectionStrings.SectionInformation.IsProtected)
{
// Decrypt the <connectionStrings> section
connectionStrings.SectionInformation.UnprotectSection();
config.Save();
// Refresh the Web.config display
DisplayWebConfig();
}
}
2 つのイベント ハンドラーで使用されるコードはほぼ同じです。 どちらも、クラスの OpenWebConfiguration
メソッドを使用して、現在のアプリケーションのWeb.config
ファイルに関する情報をWebConfigurationManager
取得することから始めます。 このメソッドは、指定された仮想パスの Web 構成ファイルを返します。 次にWeb.config
、ファイルの セクション<connectionStrings>
には、 オブジェクトをConfiguration
返す クラス s GetSection(sectionName)
メソッドをConfigurationSection
使用してアクセスします。
オブジェクトにはConfigurationSection
、構成セクションにSectionInformation
関する追加情報と機能を提供する プロパティが含まれています。 上記のコードに示すように、プロパティの IsProtected
プロパティを確認SectionInformation
することで、構成セクションが暗号化されているかどうかを判断できます。 さらに、セクションは、 プロパティProtectSection(provider)
と UnprotectSection
メソッドをSectionInformation
使用して暗号化または復号化できます。
メソッドは ProtectSection(provider)
、暗号化時に使用する保護された構成プロバイダーの名前を指定する文字列を入力として受け取ります。 EncryptConnString
Button のイベント ハンドラーで、DPAPI プロバイダーが使用されるように DataProtectionConfigurationProvider を ProtectSection(provider)
メソッドに渡します。 メソッドは UnprotectSection
、構成セクションの暗号化に使用されたプロバイダーを決定できるため、入力パラメーターは必要ありません。
または メソッドをProtectSection(provider)
呼び出した後、オブジェクトの Save
メソッドをConfiguration
呼び出して変更を保持する必要があります。UnprotectSection
構成情報が暗号化または暗号化解除され、変更が保存されたら、 を呼び出 DisplayWebConfig
して更新 Web.config
された内容を TextBox コントロールに読み込みます。
上記のコードを入力したら、ブラウザーからページに EncryptingConfigSections.aspx
アクセスしてテストします。 セクションの内容 Web.config
をプレーンテキストで <connectionStrings>
表示するページが最初に表示されます (図 3 を参照)。
図 3: TextBox コントロールと 2 つのボタン Web コントロールをページに追加する (クリックするとフルサイズの画像が表示されます)
[接続文字列の暗号化] ボタンをクリックします。 要求の検証が有効になっている場合、TextBox から WebConfigContents
ポストバックされたマークアップによって が生成 HttpRequestValidationException
され、メッセージが表示されます。クライアントから危険な Request.Form
値が検出された可能性があります。 ASP.NET 2.0 で既定で有効になっている要求検証では、エンコードされていない HTML を含むポストバックが禁止され、スクリプトインジェクション攻撃を防ぐのに役立ちます。 このチェックは、ページ レベルまたはアプリケーション レベルで無効にすることができます。 このページでオフにするには、 ディレクティブで @Page
を ValidateRequest
にfalse
設定します。 ディレクティブは @Page
、ページの宣言型マークアップの上部にあります。
<%@ Page ValidateRequest="False" ... %>
要求の検証、その目的、ページ レベルとアプリケーション レベルで無効にする方法、および HTML エンコード マークアップの方法の詳細については、「 Request Validation - Preventing Script Attacks」を参照してください。
ページの要求の検証を無効にした後、もう一度 [接続文字列の暗号化] ボタンをクリックしてみてください。 ポストバックでは、構成ファイルにアクセスし、DPAPI <connectionStrings>
プロバイダーを使用してそのセクションが暗号化されます。 その後、TextBox が更新され、新しい Web.config
コンテンツが表示されます。 図 4 に示すように、 <connectionStrings>
情報は暗号化されるようになりました。
図 4: [接続文字列の暗号化] ボタンをクリックするとセクションが <connectionString>
暗号化されます (クリックするとフルサイズの画像が表示されます)
私のコンピュータで生成された暗号化された <connectionStrings>
セクションは次のとおりですが、 要素のコンテンツ <CipherData>
の一部は簡潔にするために削除されています。
<connectionStrings
configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/...zChw==</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
注意
要素は <connectionStrings>
、暗号化の実行に使用されるプロバイダーを指定します (DataProtectionConfigurationProvider
)。 この情報は、[ 接続文字列の暗号化の UnprotectSection
解除] ボタンがクリックされたときに メソッドによって使用されます。
接続文字列情報にアクセスWeb.config
すると、コードによって、SqlDataSource コントロールから、または型指定された DataSets の TableAdapters から自動生成されたコードによって、自動的に暗号化が解除されます。 つまり、暗号化された <connectionString>
セクションの暗号化を解除するために、追加のコードやロジックを追加する必要はありません。 これを示すには、この時点で前のチュートリアルの 1 つ (「基本的なレポート」セクションの簡易表示チュートリアルなど) にアクセスしてください (~/BasicReporting/SimpleDisplay.aspx
)。 図 5 に示すように、このチュートリアルは想定したとおりに動作し、暗号化された接続文字列情報が ASP.NET ページによって自動的に復号化されていることを示しています。
図 5: データ アクセス層は接続文字列情報を自動的に復号化します (フルサイズの画像を表示する をクリックします)
セクションを <connectionStrings>
プレーンテキスト表現に戻すには、[接続文字列の暗号化解除] ボタンをクリックします。 ポストバックでは、接続文字列がプレーンテキストで Web.config
表示されます。 この時点で、このページに初めてアクセスしたときに画面が表示されます (図 3 を参照)。
手順 3: aspnet_regiis.exe を使用した構成セクションの暗号化
.NET Frameworkには、 フォルダー内のさまざまなコマンド ライン ツールが$WINDOWS$\Microsoft.NET\Framework\version\
含まれています。 たとえば、 SQL キャッシュ依存関係の使用 に関するチュートリアルでは、コマンド ライン ツールを aspnet_regsql.exe
使用して SQL キャッシュの依存関係に必要なインフラストラクチャを追加する方法について説明しました。 このフォルダーのもう 1 つの便利なコマンド ライン ツールは、 ASP.NET IIS 登録ツール (aspnet_regiis.exe
) です。 その名前が示すように、ASP.NET IIS 登録ツールは主に、ASP.NET 2.0 アプリケーションを Microsoft のプロフェッショナル レベルの Web サーバー IIS に登録するために使用されます。 IIS 関連の機能に加えて、ASP.NET IIS 登録ツールを使用して、 で Web.config
指定された構成セクションを暗号化または暗号化解除することもできます。
次のステートメントは、コマンド ライン ツールを使用して構成セクションを暗号化するために使用される一般的な構文を aspnet_regiis.exe
示しています。
aspnet_regiis.exe -pef section physical_directory -prov provider
section は暗号化する構成セクション (connectionStrings など) であり、 physical_directory は Web アプリケーションのルート ディレクトリへの完全な物理パスであり、 provider は使用する保護された構成プロバイダーの名前です (DataProtectionConfigurationProvider など)。 または、Web アプリケーションが IIS に登録されている場合は、次の構文を使用して物理パスの代わりに仮想パスを入力できます。
aspnet_regiis.exe -pe section -app virtual_directory -prov provider
次 aspnet_regiis.exe
の例では、DPAPI プロバイダーと <connectionStrings>
コンピューター レベルのキーを使用してセクションを暗号化します。
aspnet_regiis.exe -pef
"connectionStrings" "C:\Websites\ASPNET_Data_Tutorial_73_CS"
-prov "DataProtectionConfigurationProvider"
同様に、コマンド ライン ツールを aspnet_regiis.exe
使用して構成セクションの暗号化を解除できます。 スイッチを使用する代わりに、 -pef
を使用 -pdf
します (または の -pe
代わりに を使用 -pd
します)。 また、暗号化を解除するときにプロバイダー名は必要ありません。
aspnet_regiis.exe -pdf section physical_directory
-- or --
aspnet_regiis.exe -pd section -app virtual_directory
注意
コンピューターに固有のキーを使用する DPAPI プロバイダーを使用しているため、Web ページの提供元と同じコンピューターから を実行 aspnet_regiis.exe
する必要があります。 たとえば、ローカル開発マシンからこのコマンド ライン プログラムを実行し、暗号化された Web.config ファイルを運用サーバーにアップロードした場合、運用サーバーは、開発用コンピューターに固有のキーを使用して暗号化されているため、接続文字列情報の暗号化を解除できません。 RSA プロバイダーには、RSA キーを別のコンピューターにエクスポートできるため、この制限はありません。
データベース認証オプションについて
アプリケーションが Microsoft SQL Server データベースに対してクエリDELETE
INSERT
UPDATE
を発行SELECT
する前に、まずデータベースがリクエスタを識別する必要があります。 このプロセスは認証と呼ばれ、SQL Serverは 2 つの認証方法を提供します。
- Windows 認証 - アプリケーションが実行されているプロセスは、データベースとの通信に使用されます。 Visual Studio 2005 s ASP.NET Development Server を介して ASP.NET アプリケーションを実行する場合、ASP.NET アプリケーションは現在ログオンしているユーザーの ID を前提としています。 Microsoft インターネット インフォメーション サーバー (IIS) 上の ASP.NET アプリケーションの場合、ASP.NET アプリケーションは通常、 または
domainName``\NETWORK SERVICE
の ID をdomainName``\MachineName
前提としていますが、これはカスタマイズできます。 - SQL 認証 - 認証の資格情報として、ユーザー ID とパスワードの値が指定されます。 SQL 認証では、ユーザー ID とパスワードが接続文字列で提供されます。
WINDOWS 認証は、SQL 認証よりもセキュリティが強化されるため、推奨されます。 Windows 認証では、接続文字列はユーザー名とパスワードから解放され、Web サーバーとデータベース サーバーが 2 つの異なるマシンに存在する場合、資格情報はプレーンテキストでネットワーク経由で送信されません。 ただし、SQL 認証では、認証資格情報は接続文字列でハードコーディングされ、Web サーバーからデータベース サーバーにプレーンテキストで送信されます。
これらのチュートリアルでは、Windows 認証を使用しています。 接続文字列を調べることで、使用されている認証モードを確認できます。 チュートリアルの接続文字列Web.config
は次のとおりです。
Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\NORTHWND.MDF; Integrated Security=True; User Instance=True
Integrated Security=True で、ユーザー名とパスワードがない場合は、Windows 認証が使用されていることを示します。 一部の接続文字列では、Integrated Security=True ではなく Trusted Connection=Yes または Integrated Security=SSPI という用語が使用されますが、3 つすべてがWindows 認証の使用を示します。
次の例は、SQL 認証を使用する接続文字列を示しています。 $CREDENTIAL_PLACEHOLDER$
は、パスワード キーと値のペアのプレースホルダーです。 資格情報は、接続文字列内に埋め込まれています。
Server=serverName; Database=Northwind; uid=userID; $CREDENTIAL_PLACEHOLDER$
攻撃者がアプリケーションの Web.config
ファイルを表示できるとします。 SQL 認証を使用してインターネット経由でアクセスできるデータベースに接続する場合、攻撃者はこの接続文字列を使用して、SQL Management Studio または独自の Web サイト上の ASP.NET ページからデータベースに接続できます。 この脅威を軽減するには、保護された構成システムを使用して接続文字列情報Web.config
を暗号化します。
注意
SQL Serverで使用できるさまざまな種類の認証の詳細については、「セキュリティで保護された ASP.NET アプリケーションの構築: 認証、承認、およびセキュリティで保護された通信」を参照してください。 Windows と SQL の認証構文の違いを示すその他の接続文字列例については、「ConnectionStrings.com」を参照してください。
まとめ
既定では、ASP.NET アプリケーション内の拡張子を持つ .config
ファイルにブラウザーからアクセスすることはできません。 これらの種類のファイルは、データベース接続文字列、ユーザー名、パスワードなどの機密情報を含んでいる可能性があるため、返されません。 .NET 2.0 の保護された構成システムは、指定された構成セクションを暗号化できるようにすることで、機密情報をさらに保護するのに役立ちます。 RSA アルゴリズムを使用する構成プロバイダーと Windows Data Protection API (DPAPI) を使用するプロバイダーの 2 つの組み込みの保護された構成プロバイダーがあります。
このチュートリアルでは、DPAPI プロバイダーを使用して構成設定を暗号化および暗号化解除する方法について説明しました。 これは、手順 2 で説明したように、プログラムと、 aspnet_regiis.exe
手順 3 で説明したコマンド ライン ツールの両方で実現できます。 ユーザー レベルのキーを使用する方法、または代わりに RSA プロバイダーを使用する方法の詳細については、「その他の読み取り」セクションのリソースを参照してください。
プログラミングに満足!
もっと読む
このチュートリアルで説明するトピックの詳細については、次のリソースを参照してください。
- セキュリティで保護された ASP.NET アプリケーションの構築: 認証、承認、およびセキュリティで保護された通信
- ASP.NET 2.0 アプリケーションでの構成情報の暗号化
Web.config
ASP.NET 2.0 での値の暗号化- 方法: DPAPI を使用して ASP.NET 2.0 の構成セクションを暗号化する
- 方法 : RSA を使用して ASP.NET 2.0 で構成セクションを暗号化する
- .NET 2.0 の構成 API
- Windows データ保護
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。
特別な感謝
このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、テレサ・マーフィーとランディ・シュミットでした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示