web-dev-qa-db-ja.com

URLのURLエンコードスラッシュ

私の地図は:

routes.MapRoute(
   "Default",                                             // Route name
   "{controller}/{action}/{id}",                          // URL with params
   new { controller = "Home", action = "Index", id = "" } // Param defaults
);

URL http://localhost:5000/Home/About/100%2f200を使用する場合、一致するルートはありません。 URLをhttp://localhost:5000/Home/About/100に変更すると、ルートが再度照合されます。

スラッシュを含むパラメータを操作する簡単な方法はありますか?他のエスケープされた値(スペース%20)は機能しているようです。

編集:

Base64をエンコードすることは私にとってはうまくいきます。 URLが見苦しくなりますが、今のところは問題ありません。

public class UrlEncoder
{ 
    public string URLDecode(string  decode)
    {
        if (decode == null) return null;
        if (decode.StartsWith("="))
        {
            return FromBase64(decode.TrimStart('='));
        }
        else
        {
            return HttpUtility.UrlDecode( decode) ;
        }
    }

    public string UrlEncode(string encode)
    {
        if (encode == null) return null;
        string encoded = HttpUtility.PathEncode(encode);
        if (encoded.Replace("%20", "") == encode.Replace(" ", ""))
        {
            return encoded;
        }
        else
        {
            return "=" + ToBase64(encode);
        }
    }

    public string ToBase64(string encode)
    {
        Byte[] btByteArray = null;
        UTF8Encoding encoding = new UTF8Encoding();
        btByteArray = encoding.GetBytes(encode);
        string sResult = System.Convert.ToBase64String(btByteArray, 0, btByteArray.Length);
        sResult = sResult.Replace("+", "-").Replace("/", "_");
        return sResult;
    }

    public string FromBase64(string decode)
    {
        decode = decode.Replace("-", "+").Replace("_", "/");
        UTF8Encoding encoding = new UTF8Encoding();
        return encoding.GetString(Convert.FromBase64String(decode));
    }
}

EDIT1:

最終的に、最良の方法は、選択する必要のあるアイテムごとに適切にフォーマットされた文字列を保存することであることが判明しました。これは、値をエンコードするだけでデコードしないためです。すべての特殊文字は「-」になります。多くの私のdbテーブルには、この追加の列「URL」があります。データは非常に安定しているため、この方法で処理できます。 「URL」のデータが一意かどうかも確認できます。

EDIT2:

スペース文字にも注意してください。 VS統合Webサーバーでは問題なく見えますが、iis7では異なります 適切にURLエンコードスペース文字

55
Mathias F

最後のパラメーターだけの場合は、次のようにします。

routes.MapRoute(
    "Default",                                                // Route name
    "{controller}/{action}/{*id}",                            // URL with parameters
    new { controller = "Home", action = "Index", id = "" });  // Parameter defaults
48
Mehrdad Afshari

.NET 4.0ベータ2では、CLRチームが回避策を提供しています。

これをweb.configファイルに追加します。

<uri> 
    <schemeSettings>
        <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
    </schemeSettings>
</uri>

これにより、URIを記述するRFCに従ってUriクラスが動作し、エスケープを解除せずにパスでスラッシュをエスケープできます。 CLRチームは、セキュリティ上の理由で仕様から逸脱していると報告しており、これを.configファイルに設定すると、基本的に、スラッシュのエスケープを解除しないことに関連する追加のセキュリティ考慮事項の所有権を得ます。

24
Andrew Arnott

ソリューションの簡単な説明と、すでに述べた内容の要約を次に示します。

リクエスト側:

  1. パスをUrlEncodeします。
  2. 「%」を「!」に置き換えます。
  3. 要求を行います。

応答側:

  1. 「!」を置き換えます「%」で。
  2. パスをUrlDecodeします。
  3. 意図したとおりにパラメーターを使用します。

すすぎ、繰り返し、楽しんでください。

21
Don Rolling

もう1つのオプションは、クエリ文字列値を使用することです。非常に不自由ですが、カスタムエンコーディングよりも簡単です。

http://localhost:5000/Home/About?100%2f200
11
Jon Galloway

Java/Tomcat。

URLにエンコードされた「/」(%2F)がある場合、まだ問題があります。

RFC 3986-セクション2.2では、「URIコンポーネントのデータが区切り文字としての予約文字の目的と競合する場合、URIが形成される前に競合するデータをパーセントエンコードする必要があります。」 (RFC 3986-セクション2.2)

ただし、Tomcatには問題があります。

http://Tomcat.Apache.org/security-6.html -Apache Tomcat 6.0.10で修正

重要:ディレクトリトラバーサルCVE-2007-0450

Tomcatは '\'、 '%2F'および '%5C' [...]を許可します。

次のJavaシステムプロパティがTomcatに追加され、URL内のパス区切り文字の処理をさらに制御できるようになりました(両方のオプションのデフォルトはfalse):

  • org.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH:true | false
  • org.Apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH:true | false

すべてのURLがプロキシサーバー内にあるようにTomcatによって処理されることを保証できないため、コンテキストアクセスを制限するプロキシが使用されていない場合と同様に、Tomcatは常にセキュリティで保護する必要があります。

影響:6.0.0-6.0.9

したがって、%2F文字を含むURLを取得している場合、Tomcatは「400 Invalid URI:noSlash」を返します。

Tomcat起動スクリプトでバグ修正を切り替えることができます:

set Java_OPTS=%Java_OPTS% %LOGGING_CONFIG%   -Dorg.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true 
9
simonox

上記の二重エンコード/デコードの提案を回避し、HttpServerUtility.UrlTokenEncodeと対応するUrlTokenDecodeを使用するだけです。

1
silentnoise

インバウンドエンコードされた「/」問題については、「*」を追加してidパラメーターをキャッチすることで問題を修正し、エンコードされた「/」をコントロールに正しく渡すことができました(パラメーターはエンコードされた文字列でした'/')

routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{*id}",
            defaults: new 
            { 
                controller = "Control", 
                action = "Action", 
                id = UrlParameter.Optional 
            })
0
user11406534

それは.NET 4について興味深いものです。とにかく、このリンクはRFC 1738について説明し、どの文字がエンコードを必要とし、どれが単に「安全でない」かを含んでいます。 リンクテキスト

SEOフレンドリーURLが必要な場合(URLにフォーラム投稿の件名を入れたい場合など)は、エンコードをスキップし、AからZ、aからz、0から9以外のものを置き換えます。

public static string CreateSubjectSEO(string str)
    {
        int ci;
        char[] arr = str.ToCharArray();
        for (int i = 0; i < arr.Length; i++)
        {
            ci = Convert.ToInt32(arr[i]);
            if (!((ci > 47 && ci < 58) || (ci > 64 && ci < 91) || (ci > 96 && ci < 123)))
            {
                arr[i] = '-';
            }
        }
        return new string(arr);
    }
0
BillB