development

URL의 URL 인코딩 슬래시

big-blog 2020. 12. 29. 08:23
반응형

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-tables에는이 추가 열 "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 베타 2에서 CLR 팀은 해결 방법을 제공했습니다.

web.config 파일에 다음을 추가하십시오.

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

이로 인해 Uri 클래스가 URI를 설명하는 RFC에 따라 작동하여 슬래시가 이스케이프되지 않고 경로에서 이스케이프 될 수 있습니다. CLR 팀은 보안상의 이유로 사양에서 벗어났다고보고하고 .config 파일에서이를 설정하면 기본적으로 슬래시를 풀지 않는 것과 관련된 추가 보안 고려 사항에 대한 소유권을 갖게됩니다.


다음은 해결책에 대한 간단한 설명과 이미 말한 내용의 요약입니다.

요청 측 :

  1. 경로를 UrlEncode하십시오.
  2. '%'를 '!'로 바꿉니다.
  3. 요청하십시오.

Response side:

  1. Replace the '!' with '%'.
  2. UrlDecode your path.
  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.

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 

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


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

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

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

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

ReferenceURL : https://stackoverflow.com/questions/591694/url-encoded-slash-in-url

반응형