简体   繁体   English

URL中的URL编码斜杠

[英]URL-encoded slash in URL

My Map is: 我的地图是:

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

If I use the URL http://localhost:5000/Home/About/100%2f200 there is no matching route. 如果我使用URL http://localhost:5000/Home/About/100%2f200 ,则没有匹配的路由。 I change the URL to http://localhost:5000/Home/About/100 then the route is matched again. 我将URL更改为http://localhost:5000/Home/About/100然后再次匹配路由。

Is there any easy way to work with parameters that contain slashes? 有没有简单的方法来处理包含斜杠的参数? Other escaped values (space %20 ) seem to work. 其他转义值(空格%20 )似乎有效。

EDIT: 编辑:

To encode Base64 works for me. 编码Base64对我有用。 It makes the URL ugly, but that's OK for now. 它使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: EDIT1:

At the end it turned out that the best way was to save a nicely formated string for each item I need to select. 最后,结果证明最好的方法是为我需要选择的每个项目保存一个格式良好的字符串。 Thats much better because now I only encode values and never decode them. 这更好,因为现在我只编码值,从不解码它们。 All special characters become "-". 所有特殊字符都变为“ - ”。 A lot of my db-tables now have this additional column "URL". 我的很多db-table现在都有这个额外的列“URL”。 The data is pretty stable, thats why I can go this way. 数据非常稳定,这就是我可以这样做的原因。 I can even check, if the data in "URL" is unique. 如果“URL”中的数据是唯一的,我甚至可以检查。

EDIT2: EDIT2:

Also watch out for space character. 还要注意空间特征。 It looks ok on VS integrated webserver but is different on iis7 Properly url encode space character 它在VS集成网络服务器上看起来不错,但在iis7上是不同的url编码空间字符

If it's only your last parameter, you could do: 如果它只是你的最后一个参数,你可以这样做:

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

In .NET 4.0 beta 2, the CLR team has offered a workaround. 在.NET 4.0 beta 2中,CLR团队提供了一种解决方法。

Add this to your web.config file: 将其添加到您的web.config文件中:

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

This causes the Uri class to behave according to the RFC describing URIs, allowing for slashes to be escaped in the path without being unescaped. 这会导致Uri类根据描述URI的RFC行为,允许在路径中转义斜杠而不进行非转义。 The CLR team reports they deviate from the spec for security reasons, and setting this in your .config file basically makes you take ownership of the additional security considerations involved in not unescaping the slashes. 出于安全原因,CLR团队报告他们偏离了规范,并且在.config文件中设置它基本上使您获得了所有其他安全性考虑因素的所有权,而不是取消斜杠。

Here's a simple explanation of the solution and a summation of what has already been said. 以下是对解决方案的简单解释以及已经说过的内容的总结。

Request side: 要求方:

  1. UrlEncode your path. UrlEncode您的路径。
  2. Replace the '%' with '!'. 将'%'替换为'!'。
  3. Make the request. 提出要求。

Response side: 回应方:

  1. Replace the '!' 更换 '!' with '%'. 用'%'。
  2. UrlDecode your path. Url解码您的路径。
  3. Use the parameters as they were intended. 按预期使用参数。

Rinse, repeat, enjoy. 冲洗,重复,享受。

One other option is to use a querystring value. 另一个选择是使用查询字符串值。 Very lame, but simpler than custom encoding. 非常蹩脚,但比自定义编码简单。

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

Same for Java / Tomcat. Java / Tomcat也是如此。

There is still a problem if you have got an encoded "/" (%2F) in your URL. 如果您的URL中有编码的“/”(%2F),则仍然存在问题。

RFC 3986 - Section 2.2 says: "If data for a URI component would conflict with a reserved character's purpose as a delimiter, then the conflicting data must be percent-encoded before the URI is formed." RFC 3986 - 第2.2节说:“如果URI组件的数据与保留字符作为分隔符的目的冲突,那么冲突数据必须在形成URI之前进行百分比编码。” (RFC 3986 - Section 2.2) (RFC 3986 - 第2.2节)

But there is an Issue with Tomcat: 但Tomcat存在一个问题:

http://tomcat.apache.org/security-6.html - Fixed in Apache Tomcat 6.0.10 http://tomcat.apache.org/security-6.html - 已在Apache Tomcat 6.0.10中修复

important: Directory traversal CVE-2007-0450 重要:目录遍历CVE-2007-0450

Tomcat permits '\\', '%2F' and '%5C' [...] . Tomcat允许'\\','%2F'和'%5C'[...]。

The following Java system properties have been added to Tomcat to provide additional control of the handling of path delimiters in URLs (both options default to false): 已将以下Java系统属性添加到Tomcat,以提供对URL中路径分隔符处理的额外控制(两个选项都默认为false):

  • org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH: true|false org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH:true | false
  • org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH: true|false org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH:true | false

Due to the impossibility to guarantee that all URLs are handled by Tomcat as they are in proxy servers, Tomcat should always be secured as if no proxy restricting context access was used. 由于无法保证所有URL都由Tomcat处理,因为它们位于代理服务器中,因此应始终保护Tomcat,就好像没有使用代理限制上下文访问一样。

Affects: 6.0.0-6.0.9 影响:6.0.0-6.0.9

So if you have got an URL with the %2F character, Tomcat returns: "400 Invalid URI: noSlash" 因此,如果您有一个带有%2F字符的URL,Tomcat将返回:“400无效的URI:noSlash”

You can switch of the bugfix in the Tomcat startup script: 您可以在Tomcat启动脚本中切换错误修复:

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

您可以避免上面的双重编码/解码建议,只需使用HttpServerUtility.UrlTokenEncode和相应的UrlTokenDecode。

That's interesting about .NET 4. Anyway, this link describes RFC 1738 and includes which characters need encoding and which are just "unsafe". 这对于.NET 4来说很有意思。无论如何,这个链接描述了RFC 1738,包括哪些字符需要编码,哪些只是“不安全”。 link text 链接文字

If I want an SEO friendly URL, (like when you want to put a forum post subject in the URL), is skip encoding and replace anything that's not AZ, az, 0-9. 如果我想要一个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);
    }

For inbound encoded '/' issue, I was able to fix my issue by adding '*' to catchall the id parameter and then was able to passing an encoded '/' into the the control correctly (the parameter was a string with an encoded '/') 对于入站编码'/'问题,我能够通过添加'*'来修复我的问题来捕获id参数,然后能够正确地将编码的'/'传递给控件(参数是带编码的字符串) '/')

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

As suggested here when the problem was faced by Symfony 1.x developers (+ suggested in PHP comments for urlencode() ): 作为建议在这里当问题面临的Symfony 1.x开发(+中建议对PHP的意见urlencode()

  • Encode '/' to '%2F' before urlencode() urlencode()之前将'/'编码为'%2F'
  • Decode '%2F' to '/' after (if necessary) urldecode() 在(如果需要) urldecode()之后将'%2F'解码为'/'

Note: you can use rawurlencode() , but you will still have to urlencode '/' twice. 注意:您可以使用rawurlencode() ,但仍需要两次urlencode'/'。

Advantages: 好处:

  • Avoids the need of additional escaping processes (if replacing '/' with a special character like '!' or '_') 避免需要额外的转义过程(如果用'!'或'_'等特殊字符替换'/')
  • Do not relies on any server setting such as AllowEncodedSlashes for Apache 不依赖于任何服务器设置,例如Apache的AllowEncodedSlashes

Just use Server.UrlDecode . 只需使用Server.UrlDecode It will work, I've tested. 它会起作用,我已经测试过了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM