URL 中的 URL 编码斜杠

发布于 2024-07-15 00:36:07 字数 2224 浏览 4 评论 0原文

我的地图是:

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:

最后发现最好的方法是为我需要选择的每个项目保存一个格式良好的字符串。 这好多了,因为现在我只对值进行编码,从不解码它们。 所有特殊字符都变成“-”。 我的很多数据库表现在都有这个附加列“URL”。 数据相当稳定,这就是我可以走这条路的原因。 我什至可以检查“URL”中的数据是否唯一。

EDIT2:

还要注意空格字符。 它在 VS 集成网络服务器上看起来没问题,但在 iis7 上则不同 正确 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.
I change the URL to http://localhost:5000/Home/About/100 then the route is matched again.

Is there any easy way to work with parameters that contain slashes? Other escaped values (space %20) seem to work.

EDIT:

To encode Base64 works for me. It makes the URL ugly, but that's OK for now.

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:

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". The data is pretty stable, thats why I can go this way. I can even check, if the data in "URL" is unique.

EDIT2:

Also watch out for space character. It looks ok on VS integrated webserver but is different on iis7 Properly url encode space character

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

同展鸳鸯锦 2024-07-22 00:36:07

如果这只是你的最后一个参数,你可以这样做:

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

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
与之呼应 2024-07-22 00:36:07

这是解决方案的简单解释以及已经说过的内容的总结。

请求方:

  1. UrlEncode 您的路径。
  2. 将“%”替换为“!”。
  3. 提出请求。

响应方:

  1. 替换“!” 和 '%'。
  2. UrlDecode 你的路径。
  3. 按预期使用参数。

冲洗,重复,享受。

Here's a simple explanation of the solution and a summation of what has already been said.

Request side:

  1. UrlEncode your path.
  2. Replace the '%' with '!'.
  3. Make the request.

Response side:

  1. Replace the '!' with '%'.
  2. UrlDecode your path.
  3. Use the parameters as they were intended.

Rinse, repeat, enjoy.

囍孤女 2024-07-22 00:36:07

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:
    真|假
  • org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH:
    真|假

由于无法保证
所有 URL 均由 Tomcat 处理
它们位于代理服务器、Tomcat 中
应始终受到保护,就好像没有一样
代理限制上下文访问是
使用过。

影响:6.0.0-6.0.9

因此,如果您的 URL 包含 %2F 字符,Tomcat 将返回:“400 Invalid URI: noSlash”

您可以在 Tomcat 启动脚本中切换错误修复:

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

Same for Java / Tomcat.

There is still a problem if you have got an encoded "/" (%2F) in your URL.

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 - Section 2.2)

But there is an Issue with Tomcat:

http://tomcat.apache.org/security-6.html - Fixed in Apache Tomcat 6.0.10

important: Directory traversal CVE-2007-0450

Tomcat permits '\', '%2F' and '%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):

  • org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH:
    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.

Affects: 6.0.0-6.0.9

So if you have got an URL with the %2F character, Tomcat returns: "400 Invalid URI: noSlash"

You can switch of the bugfix in the Tomcat startup script:

set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%   -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true 
只是我以为 2024-07-22 00:36:07

另一种选择是使用查询字符串值。 非常蹩脚,但比自定义编码更简单。

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

One other option is to use a querystring value. Very lame, but simpler than custom encoding.

http://localhost:5000/Home/About?100%2f200
2024-07-22 00:36:07

在 .NET 4.0 beta 2 中,CLR 团队提供了一种解决方法。

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

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

这会导致 Uri 类根据描述 URI 的 RFC 进行操作,从而允许在路径中转义斜杠而不进行转义。 CLR 团队报告说,出于安全原因,他们偏离了规范,并且在 .config 文件中进行设置基本上可以让您承担与不转义斜线相关的额外安全考虑。

In .NET 4.0 beta 2, the CLR team has offered a workaround.

Add this to your web.config file:

<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. 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.

羅雙樹 2024-07-22 00:36:07

.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);
    }

That's interesting about .NET 4. Anyway, this link describes RFC 1738 and includes which characters need encoding and which are just "unsafe".
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 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);
    }
も让我眼熟你 2024-07-22 00:36:07

对于入站编码的“/”问题,我能够通过添加“*”来捕获所有 id 参数来解决我的问题,然后能够将编码的“/”正确传递到控件中(该参数是带有编码的字符串) '/')

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

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 '/')

routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{*id}",
            defaults: new 
            { 
                controller = "Control", 
                action = "Action", 
                id = UrlParameter.Optional 
            })
蒗幽 2024-07-22 00:36:07

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

You can avoid the double encoding/decoding suggestions above and simply use HttpServerUtility.UrlTokenEncode and the corresponding UrlTokenDecode.

鸵鸟症 2024-07-22 00:36:07

正如此处所建议的,当问题出现在Symfony 1.x 开发人员(+ 在 PHP 注释中建议 urlencode( )):

  • urlencode()之前将'/'编码为'%2F',
  • 在(如有必要)urldecode()之后将'%2F'解码为'/' )

注意:您可以使用 rawurlencode(),但您仍然需要对 '/' 进行 urlencode 两次。

优点:

  • 避免需要额外的转义过程(如果用“!”或“_”等特殊字符替换“/”)
  • 不依赖任何服务器设置,例如 Apache 的 AllowEncodedSlashes

As suggested here when the problem was faced by Symfony 1.x developers (+ suggested in PHP comments for urlencode()):

  • Encode '/' to '%2F' before urlencode()
  • Decode '%2F' to '/' after (if necessary) urldecode()

Note: you can use rawurlencode(), but you will still have to urlencode '/' twice.

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
枫以 2024-07-22 00:36:07

只需使用Server.UrlDecode。 它会起作用,我已经测试过。

Just use Server.UrlDecode. It will work, I've tested.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文