2012-02-01 4 views
14

일반적으로 질문에이 제목을 넣지는 않겠지 만 버그 (또는 설계 상으로는?)가 확실합니다.ASP.NET MVC 3 라우팅에서 발생 가능한 버그?

새로운 ASP.NET MVC 3 웹 응용 프로그램을 만들었습니다.

그런 다음/홈/정보 페이지로갔습니다.

는이 페이지의 URL은 다음과 같습니다

http://localhost:51419/Home/About

그런 다음 내가이 URL을 변경 :

http://localhost:51419/(A(a))/Home/About

그리고 페이지가 일? 경로 값을 보면 controller = Home, Action = About입니다. 첫 번째 부분은 무시 되었습니까?

그리고 나는 소스에있는 모든 링크를 보면 :

<link href="/(A(a))/Content/Site.css" rel="stylesheet" type="text/css" /> 
<script src="/(A(a))/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script> 
<script src="/(A(a))/Scripts/modernizr-1.7.min.js" type="text/javascript"></script> 

<li><a href="/(A(a))/">Home</a></li> 
<li><a href="/(A(a))/Home/About">About</a></li> 

은 첫 번째 부분한다고 주장 어떻게 보는가? 그것은 라우팅 엔진이 도메인이나 뭔가의 일부라고 생각하는 것과 같습니다. 내가 URL을 변경하면 있기 때문에하는 정규식 일입니다 느낌이있어

:

http://localhost:51419/(a(a))/Home/About

은 (예를 들어, 소문자로 대문자 A를 변경)

그것은 404의.

누구든지이 문제에 대해 의견을 개진 할 수 있습니까? 이것은 버그입니까, 디자인입니까?

+2

제목에 "가능한 버그"가있는 게시물이 가치가있는 경우는 드뭅니다. IMO. 이것은 하나입니다. –

+1

@AndrewBarber - 알아요. :) 그것은이 것을 가로 질러 온 순수한 우연한 우연입니다. Google은 응용 프로그램의 버그로 인해 이상한 URL에 지침이 포함 된 색인을 생성했습니다. – RPM1984

답변

5

이 내용은 ASP.NET 파이프 라인의 쿠키가없는 세션과 관련이있는 것으로 보입니다.

// This function is called for all requests -- it must be performant. 
    // In the common case (i.e. value not present in the URI, it must not 
    // look at the headers collection 
    internal void RemoveCookielessValuesFromPath() 
    { 
     // See if the path contains "/(XXXXX)/" 
     string path  = _Context.Request.ClientFilePath.VirtualPathString; 
     // Optimize for the common case where there is no cookie 
     if (path.IndexOf('(') == -1) { 
      return; 
     } 
     int  endPos = path.LastIndexOf(")/", StringComparison.Ordinal); 
     int  startPos = (endPos > 2 ? path.LastIndexOf("/(", endPos - 1, endPos, StringComparison.Ordinal) : -1); 

     if (startPos < 0) // pattern not found: common case, exit immediately 
      return; 

     if (_Headers == null) // Header should always be processed first 
      GetCookielessValuesFromHeader(); 

     // if the path contains a cookie, remove it 
     if (IsValidHeader(path, startPos + 2, endPos)) 
     { 
      // only set _Headers if not already set 
      if (_Headers == null) { 
       _Headers = path.Substring(startPos + 2, endPos - startPos - 2); 
      } 
      // Rewrite the path 
      path = path.Substring(0, startPos) + path.Substring(endPos+1); 

      // remove cookie from ClientFilePath 
      _Context.Request.ClientFilePath = VirtualPath.CreateAbsolute(path); 
      // get and append query string to path if it exists 
      string rawUrl = _Context.Request.RawUrl; 
      int qsIndex = rawUrl.IndexOf('?'); 
      if (qsIndex > -1) { 
       path = path + rawUrl.Substring(qsIndex); 
      } 
      // remove cookie from RawUrl 
      _Context.Request.RawUrl = path; 

      if (!String.IsNullOrEmpty(_Headers)) { 
       _Context.Request.ValidateCookielessHeaderIfRequiredByConfig(_Headers); // ensure that the path doesn't contain invalid chars 
       _Context.Response.SetAppPathModifier("(" + _Headers + ")"); 

       // For Cassini and scenarios where aspnet_filter.dll is not used, 
       // HttpRequest.FilePath also needs to have the cookie removed. 
       string filePath = _Context.Request.FilePath; 
       string newFilePath = _Context.Response.RemoveAppPathModifier(filePath); 
       if (!Object.ReferenceEquals(filePath, newFilePath)) { 
        _Context.RewritePath(VirtualPath.CreateAbsolute(newFilePath), 
             _Context.Request.PathInfoObject, 
             null /*newQueryString*/, 
             false /*setClientFilePath*/); 
       } 
      } 
     } 
    } 

귀하의 패턴이 일치 : 나는 @pjumble 분석에 동의

/////////////////////////////////////////////////////////////////////// 
    /////////////////////////////////////////////////////////////////////// 
    // Make sure sub-string if of the pattern: A(XXXX)N(XXXXX)P(XXXXX) and so on. 
    static private bool IsValidHeader(string path, int startPos, int endPos) 
    { 
     if (endPos - startPos < 3) // Minimum len is "X()" 
      return false; 

     while (startPos <= endPos - 3) { // Each iteration deals with one "A(XXXX)" pattern 

      if (path[startPos] < 'A' || path[startPos] > 'Z') // Make sure pattern starts with a capital letter 
       return false; 

      if (path[startPos + 1] != '(') // Make sure next char is '(' 
       return false; 

      startPos += 2; 
      bool found = false; 
      for (; startPos < endPos; startPos++) { // Find the ending ')' 

       if (path[startPos] == ')') { // found it! 
        startPos++; // Set position for the next pattern 
        found = true; 
        break; // Break out of this for-loop. 
       } 

       if (path[startPos] == '/') { // Can't contain path separaters 
        return false; 
       } 
      } 
      if (!found) { 
       return false; // Ending ')' not found! 
      } 
     } 

     if (startPos < endPos) // All chars consumed? 
      return false; 

     return true; 
    } 
+0

흠, sooo ... 이거 버그 야? 그 코드가 의미있는 것처럼 그것의 ASP.NET 코어 일은 확실하지 않습니다. 그러나 ASP.NET 라우팅 엔진 (잘, MVC 하나 이상 라우팅), IMO는 경로의 일부로이를 받아들이지 않아야합니다 (예 : 일치하지 않아야 함). 나는 MS로 이것을 제기해야합니까? – RPM1984

+0

@ RPM1984 아니요, 명확하게 쿠키가 제공되지 않을 때 어떤 사용자가 로그인했는지 추적하는 방법입니다. 그냥 당신이 이것을 알아 차리지 못했고 모든 것이 괜찮을 것입니다. –

+0

@RobertLevy - 나는 그것을 무시할 수 없다. 이것은 실제로 라이브 응용 프로그램으로 나에게 일어나고있다. 내가 코멘트에서 말했듯이, 구글은이 패턴과 일치하는 이상한 URL을 색인하고있다. 그래서 MVC가 유효한 경로로 그것들을 받아들이 기 때문에, 그들은 단지 나의 컨트롤러에 도착한 후 나중에 죽어 가고 있습니다. 정말로 그들이 가야할 때부터 404'ed해야합니다. URL도 무작위이므로 재 작성을 쉽게 할 수 없습니다. 충분히 공정한이 ASP.NET에서 "의도적으로"설계되었지만 이것이 MVC의 버그라고 생각합니다. 이 경로를 받아 들여서는 안됩니다. – RPM1984

-1

있지만 요청을 처리하는 동안 그것은 CookielessHelper.cs (System.Web.Security) 내부에 해당 URL 패턴을 제거합니다 그의 해결책.
폼 인증 또는 익명 인증에 대해 쿠키없는 인증을 사용하지 않습니다.

이렇게하면 쿠키가 비활성화 된 사용자가 인증되지 않습니다. 그러나 어쨌든 누구가 걱정하는지, 모두는 현대 웹 사이트가없이 일하지 않기 때문에 활성화 된 과자를 지금 가지고있다. Web.config의에서

추가

<anonymousIdentification enabled="false" /> 
<authentication mode="None" /> 

또는

<anonymousIdentification enabled="true" cookieless="UseCookies" ... /> 
<authentication mode="Forms"> 
    <forms name="Auth" cookieless="UseCookies" ... /> 
</authentication> 
+0

BTW, @ pjumble의 "해결책"은 무엇인가요, 나는 진단을 보지 못했습니다. – RPM1984

+0

당신은 .net의 URL 구문 분석에서 어리석은 무의미한 단점 때문에 로그인의 일부 집합을 차단할 수 있습니까? –

+0

"어쨌든 누가 상관하니?"영업 부서의 대부분은 ... – Basic

0

당신은 당신의 경로 매핑에 IgnoreRoute를 추가하려고 할 수 있습니다 -하지만 난 제공 할 어떤 형식 확실하지 않다 인정 가능한 모든 쿠키없는 경로와 일치시킵니다.