【C#】HTML特殊文字をエンコード・デコードして安全に扱う方法

目次

概要

ユーザーからの入力テキストをWebページ等で表示する際、<> などの特殊文字を無害な形式(実体参照)に変換(エスケープ)する処理です。 クロスサイトスクリプティング(XSS)攻撃を防いだり、HTMLタグとしての誤解釈による表示崩れを防ぐために使用します。また、エンコードされた文字列を元の状態に戻すデコード処理についても解説します。

仕様(入出力)

  • 入力: HTMLタグや特殊記号を含む文字列。
  • 出力: 特殊文字がエンコード(&lt; 等に変換)された文字列、およびそれをデコードして復元した文字列。
  • 前提: .NET標準ライブラリ(System.Net)を使用。

基本の使い方

System.Net.WebUtility クラスの静的メソッドを使用します。

string rawText = "<div>Test</div>";

// エンコード: <div>Test</div> -> &lt;div&gt;Test&lt;/div&gt;
string safeText = WebUtility.HtmlEncode(rawText);

// デコード: &lt;div&gt; -> <div>
string originalText = WebUtility.HtmlDecode(safeText);

コード全文

ここでは「ユーザーが投稿したコメント」を想定し、悪意のあるスクリプトタグが含まれていても安全に表示できるように変換するシミュレーションを行います。

using System;
using System.Net;

class Program
{
    static void Main()
    {
        // 1. ユーザーからの入力(悪意のあるコードや特殊文字が含まれている想定)
        string userInput = "<script>alert('XSS Attack!');</script> \"Rock & Roll\"";

        Console.WriteLine("--- 1. 元の文字列 ---");
        Console.WriteLine(userInput);

        // 2. HTMLエンコード(無害化)
        // <, >, &, " などの特殊文字をHTMLエンティティに変換します
        string encodedContent = WebUtility.HtmlEncode(userInput);

        Console.WriteLine("\n--- 2. エンコード後の文字列(安全) ---");
        Console.WriteLine(encodedContent);
        // 出力結果: &lt;script&gt;alert(&#39;XSS Attack!&#39;);&lt;/script&gt; &quot;Rock &amp; Roll&quot;

        // 3. HTMLデコード(復元)
        // データベースから取り出して編集画面に表示する場合などに元の文字に戻します
        string decodedContent = WebUtility.HtmlDecode(encodedContent);

        Console.WriteLine("\n--- 3. デコード後の文字列(復元) ---");
        Console.WriteLine(decodedContent);
        
        // 復元チェック
        if (userInput == decodedContent)
        {
            Console.WriteLine("\n判定: 完全に復元されました。");
        }
    }
}

カスタムポイント

  • URLのエンコード: HTML本文ではなく、URLパラメータとして安全な形式にしたい場合は WebUtility.UrlEncode を使用してください(スペースが + になるなど変換ルールが異なります)。
  • Javascript文字列への埋め込み: HTML内ではなく、<script> ブロック内の変数に値を埋め込む場合は、WebUtility.HtmlEncode だけでは不十分な場合があります。JavaScript用のエスケープ(HttpUtility.JavaScriptStringEncode 等)を検討してください。

注意点

  1. WebUtility vs HttpUtility: 古いASP.NETアプリでは System.Web.HttpUtility が使われていましたが、.NET Core以降やコンソールアプリでは System.Net.WebUtility が標準的に使用可能です。
  2. 二重エンコード: 既にエンコードされている文字列を再度エンコードすると、&amp;lt; のようになり、正しく表示されなくなります。入力データが既にエスケープ済みでないか確認してください。
  3. 属性値への利用: HtmlEncode は基本的に要素の中身(TextContent)向けです。HTML属性(例: href="...")に埋め込む場合は、引用符の処理が適切に行われるか注意が必要です(WebUtility はシングルクォートも &#39; に変換するため概ね安全ですが、コンテキストによります)。

応用

より厳密な制御ができる HtmlEncoder (.NET Core / 5+)

パフォーマンスを重視する場合や、日本語文字をエスケープしたくない(デフォルトでは日本語も &#x...; になる場合がある)場合は、System.Text.Encodings.Web を使用します。

using System.Text.Encodings.Web;
using System.Text.Unicode;

// 日本語をエスケープしない設定を作成
var options = new System.Text.Encodings.Web.TextEncoderSettings(UnicodeRanges.All);
var encoder = HtmlEncoder.Create(options);

string text = "<p>こんにちは</p>";
string result = encoder.Encode(text); 
// 結果: &lt;p&gt;こんにちは&lt;/p&gt;
// (WebUtilityだと日本語はそのままですが、こちらの標準設定だと日本語もエスケープされるため設定が必要)

まとめ

XSS脆弱性を防ぐための最も基本的かつ重要な処理です。

WebアプリケーションやHTMLメール生成などで、ユーザー入力を扱う場合は必ず HTMLエンコード を行ってください。

標準的な用途では System.Net.WebUtility.HtmlEncode が手軽で便利です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次