web-dev-qa-db-ja.com

MS Ajaxで使用するために.NET文字列をJavaScript文字列にエンコードする標準的な方法はありますか?

.NET 3.5のMS ScriptManagerのRegisterStartUpScriptメソッドを使用して、SQL Server例外の出力をクライアントに渡そうとしています。これは一部のエラーでは正常に機能しますが、例外に一重引用符が含まれる場合、アラートは失敗します。

ただし、単一引用符だけをエスケープしたくありません。 JavaScriptで使用する特別な文字をエスケープするために呼び出すことができる標準関数はありますか?

string scriptstring = "alert('" + ex.Message + "');";         
ScriptManager.RegisterStartupScript(this, this.GetType(), "Alert", scriptstring , true);

[〜#〜] edit [〜#〜]

@tpeczekに感謝します。コードalmostは私のために機能しました:)が、わずかな修正(一重引用符のエスケープ)で処理できます。

ここに修正版を含めました...

public class JSEncode
{
    /// <summary>
    /// Encodes a string to be represented as a string literal. The format
    /// is essentially a JSON string.
    /// 
    /// The string returned includes outer quotes 
    /// Example Output: "Hello \"Rick\"!\r\nRock on"
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string EncodeJsString(string s)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("\"");
        foreach (char c in s)
        {
            switch (c)
            {
                case '\'':
                    sb.Append("\\\'");
                    break;
                case '\"':
                    sb.Append("\\\"");
                    break;
                case '\\':
                    sb.Append("\\\\");
                    break;
                case '\b':
                    sb.Append("\\b");
                    break;
                case '\f':
                    sb.Append("\\f");
                    break;
                case '\n':
                    sb.Append("\\n");
                    break;
                case '\r':
                    sb.Append("\\r");
                    break;
                case '\t':
                    sb.Append("\\t");
                    break;
                default:
                    int i = (int)c;
                    if (i < 32 || i > 127)
                    {
                        sb.AppendFormat("\\u{0:X04}", i);
                    }
                    else
                    {
                        sb.Append(c);
                    }
                    break;
            }
        }
        sb.Append("\"");

        return sb.ToString();
    }
}

下記のとおり-元のソース: here

73
Rich Andrews
179
Russ Cam

この関数の問題は、通常HTMLのカプセル化でアウトオブバンドである文字をエンコードしないことです。そのため、属性値の中に"を含む文字列を含めようとした場合、またはスクリプト要素内にシーケンス</script>の文字列がありました。それはスクリプトインジェクションとXSSにつながる可能性があります。

以下を追加できます:

            case '<':
                sb.Append("\\x3C");
                break;
            case '"':
                sb.Append("\\x22");
                break;
            case '&':
                sb.Append("\\x26");
                break;

一般に、独自のJS文字列リテラルエンコーダーを作成するよりも、標準のJSONエンコーダーを使用する方が適切です。これにより、単なる文字列ではなく、単純なデータ型をJSに渡すことができます。

.NET 3.5では JavaScriptSerializer を取得しますが、このdoes<\u003Cにエンコードすることに注意してください(出力は適切です) <script>要素で使用する場合)does n't&または"をエンコードするため、そのようなコンテンツを属性値に含めるにはHTMLエスケープが必要ですXHTMLスクリプト要素にはCDATAラッパーが必要です。

(多くのJSONエンコーダーと同様に、U + 2028 LINE SEPARATORおよびU + 2029 PARAGRAPH SEPARATOR文字のエンコードも失敗します。上記のコードは、すべての非ASCII文字をエスケープするため、失敗します。 JavaScriptはASCII newline。)と同じように役に立たないため、これらの文字はJS文字列リテラルに含まれます。

10
bobince

これは古いスレッドですが、.Net 2以降で動作するJavascriptエンコードメソッドを持つMicrosoft AntiXSSライブラリについて知りたい場合があります。

http://msdn.Microsoft.com/en-gb/security/aa973814.aspx

3
DomBat