簡體   English   中英

URL中的URL編碼斜杠

[英]URL-encoded slash in 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-table現在都有這個額外的列“URL”。 數據非常穩定,這就是我可以這樣做的原因。 如果“URL”中的數據是唯一的,我甚至可以檢查。

EDIT2:

還要注意空間特征。 它在VS集成網絡服務器上看起來不錯,但在iis7上是不同的url編碼空間字符

如果它只是你的最后一個參數,你可以這樣做:

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

在.NET 4.0 beta 2中,CLR團隊提供了一種解決方法。

將其添加到您的web.config文件中:

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

這會導致Uri類根據描述URI的RFC行為,允許在路徑中轉義斜杠而不進行非轉義。 出於安全原因,CLR團隊報告他們偏離了規范,並且在.config文件中設置它基本上使您獲得了所有其他安全性考慮因素的所有權,而不是取消斜杠。

以下是對解決方案的簡單解釋以及已經說過的內容的總結。

要求方:

  1. UrlEncode您的路徑。
  2. 將'%'替換為'!'。
  3. 提出要求。

回應方:

  1. 更換 '!' 用'%'。
  2. Url解碼您的路徑。
  3. 按預期使用參數。

沖洗,重復,享受。

另一個選擇是使用查詢字符串值。 非常蹩腳,但比自定義編碼簡單。

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

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無效的URI:noSlash”

您可以在Tomcat啟動腳本中切換錯誤修復:

set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%   -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true 

您可以避免上面的雙重編碼/解碼建議,只需使用HttpServerUtility.UrlTokenEncode和相應的UrlTokenDecode。

這對於.NET 4來說很有意思。無論如何,這個鏈接描述了RFC 1738,包括哪些字符需要編碼,哪些只是“不安全”。 鏈接文字

如果我想要一個SEO友好的URL,(比如當你想在URL中放置一個論壇帖子主題時),跳過編碼並替換任何不是AZ,az,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);
    }

對於入站編碼'/'問題,我能夠通過添加'*'來修復我的問題來捕獲id參數,然后能夠正確地將編碼的'/'傳遞給控件(參數是帶編碼的字符串) '/')

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

作為建議在這里當問題面臨的Symfony 1.x開發(+中建議對PHP的意見urlencode()

  • urlencode()之前將'/'編碼為'%2F'
  • 在(如果需要) urldecode()之后將'%2F'解碼為'/'

注意:您可以使用rawurlencode() ,但仍需要兩次urlencode'/'。

好處:

  • 避免需要額外的轉義過程(如果用'!'或'_'等特殊字符替換'/')
  • 不依賴於任何服務器設置,例如Apache的AllowEncodedSlashes

只需使用Server.UrlDecode 它會起作用,我已經測試過了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM