次の方法で共有


UTF-7 コードパスは廃止予定です

UTF-7 エンコードはアプリケーション間で広く使用されなくなり、多くの仕様でインターチェンジでの 使用が禁止 されるようになりました。 また、UTF-7 でエンコードされたデータが発生することが予想されないアプリケーションでは 、攻撃ベクトルとして使用 されることもあります。 Microsoft は、エラー検出を提供しないため、 System.Text.UTF7Encoding の使用に対して警告します。

その結果、 Encoding.UTF7 プロパティと UTF7Encoding コンストラクターは廃止されました。 さらに、 Encoding.GetEncodingEncoding.GetEncodings では、 UTF-7を指定できなくなります。

変更の説明

以前は、 Encoding.GetEncoding API を使用して UTF-7 エンコードのインスタンスを作成できました。 例えば次が挙げられます。

Encoding enc1 = Encoding.GetEncoding("utf-7"); // By name.
Encoding enc2 = Encoding.GetEncoding(65000); // By code page.

さらに、UTF-7 エンコードを表すインスタンスは、システムに登録されているすべてのEncoding.GetEncodings() インスタンスを列挙するEncoding メソッドによって列挙されました。

.NET 5 以降では、 Encoding.UTF7 プロパティと UTF7Encoding コンストラクターは廃止され、警告 SYSLIB0001が生成されます。 ただし、 UTF7Encoding クラスの使用時に呼び出し元が受け取る警告の数を減らすために、 UTF7Encoding 型自体は古い形式としてマークされません。

// The next line generates warning SYSLIB0001.
UTF7Encoding enc = new UTF7Encoding();
// The next line does not generate a warning.
byte[] bytes = enc.GetBytes("Hello world!");

さらに、 Encoding.GetEncoding メソッドはエンコード名 utf-7 とコード ページ 65000unknownとして扱います。 エンコードを unknown として扱うと、メソッドは ArgumentExceptionを送出します。

// Throws ArgumentException, same as calling Encoding.GetEncoding("unknown").
Encoding enc = Encoding.GetEncoding("utf-7");

最後に、 Encoding.GetEncodings() メソッドは、返される EncodingInfo 配列に UTF-7 エンコードを含めません。 エンコードはインスタンス化できないため、除外されます。

foreach (EncodingInfo encInfo in Encoding.GetEncodings())
{
    // The next line would throw if GetEncodings included UTF-7.
    Encoding enc = Encoding.GetEncoding(encInfo.Name);
}

変更の理由

多くのアプリケーションは、信頼されていないソースによって提供されるエンコード名の値を使用して Encoding.GetEncoding("encoding-name") を呼び出します。 たとえば、Web クライアントまたはサーバーは、charset ヘッダーのContent-Type部分を受け取り、検証せずに値をEncoding.GetEncodingに直接渡すことができます。 これにより、悪意のあるエンドポイントが Content-Type: ...; charset=utf-7を指定する可能性があります。これにより、受信側のアプリケーションが誤って動作する可能性があります。

さらに、UTF-7 コード パスを無効にすると、Blazor で使用されるコンパイラなどのコンパイラを最適化して、結果のアプリケーションからこれらのコード パスを完全に削除できます。 その結果、コンパイルされたアプリケーションの実行効率が高くなり、ディスク領域が少なくなります。

導入されたバージョン

5.0

ほとんどの場合、アクションを実行する必要はありません。 ただし、以前に UTF-7 関連のコード パスをアクティブ化したアプリの場合は、次のガイダンスを検討してください。

  • 信頼されていないソースによって指定された不明なエンコード名で Encoding.GetEncoding をアプリが呼び出す場合:

    代わりに、エンコード名を構成可能な許可リストと比較します。 構成可能な許可リストには、少なくとも業界標準の "utf-8" が含まれている必要があります。 クライアントと規制の要件によっては、"GB18030" などのリージョン固有のエンコードを許可する必要がある場合もあります。

    許可リストを実装しない場合、Encoding.GetEncoding は、システムに組み込まれている Encoding や、カスタム EncodingProvider 経由で登録された Encoding を返します。 サービスの要件を監査して、これが目的の動作であることを検証します。 この記事で後述する互換性スイッチをアプリケーションで再度有効にしない限り、UTF-7 は既定で引き続き無効になります。

  • 独自のプロトコルまたはファイル形式で Encoding.UTF7 または UTF7Encoding を使用している場合:

    Encoding.UTF8またはUTF8Encodingの使用に切り替えます。 UTF-8 は業界標準であり、言語、オペレーティング システム、ランタイム全体で広くサポートされています。 UTF-8 を使用すると、コードの将来のメンテナンスが容易になり、他のエコシステムとの相互運用が容易になります。

  • Encoding インスタンスをEncoding.UTF7と比較する場合:

    代わりに、既知の UTF-7 コード ページ ( 65000) に対してチェックを実行することを検討してください。 コードページを参照することで、警告を回避し、new UTF7Encoding() を呼び出したり、型をサブクラス化したりする場合など、いくつかのエッジケースも処理できます。

    void DoSomething(Encoding enc)
    {
        // Don't perform the check this way.
        // It produces a warning and misses some edge cases.
        if (enc == Encoding.UTF7)
        {
            // Encoding is UTF-7.
        }
    
        // Instead, perform the check this way.
        if (enc != null && enc.CodePage == 65000)
        {
            // Encoding is UTF-7.
        }
    }
    
  • Encoding.UTF7またはUTF7Encodingを使用する必要がある場合:

    コード内またはプロジェクトの SYSLIB0001 ファイル内で、警告を抑制できます。

    #pragma warning disable SYSLIB0001 // Disable the warning.
    Encoding enc = Encoding.UTF7;
    #pragma warning restore SYSLIB0001 // Re-enable the warning.
    
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
       <TargetFramework>net5.0</TargetFramework>
       <!-- NoWarn below suppresses SYSLIB0001 project-wide -->
       <NoWarn>$(NoWarn);SYSLIB0001</NoWarn>
      </PropertyGroup>
    </Project>
    

    SYSLIB0001を抑制すると、Encoding.UTF7UTF7Encodingの難読化の警告のみが無効になります。 他の警告を無効にしたり、 Encoding.GetEncodingなどの API の動作を変更したりすることはありません。

  • Encoding.GetEncoding("utf-7", ...)をサポートする必要がある場合:

    互換性スイッチを使用して、このサポートを再度有効にすることができます。 この互換性スイッチは、次の例に示すように、アプリケーションの .csprojファイルまたはランタイム構成ファイルで指定できます。

    アプリケーションの .csproj ファイルで次の手順を実行します

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
       <TargetFramework>net5.0</TargetFramework>
       <!-- Re-enable support for UTF-7 -->
       <EnableUnsafeUTF7Encoding>true</EnableUnsafeUTF7Encoding>
      </PropertyGroup>
    </Project>
    

    アプリケーションの runtimeconfig.template.json ファイルで、

    {
      "configProperties": {
        "System.Text.Encoding.EnableUnsafeUTF7Encoding": true
      }
    }
    

    ヒント

    UTF-7 のサポートを再度有効にする場合は、 Encoding.GetEncodingを呼び出すコードのセキュリティ レビューを実行する必要があります。

影響を受ける API