Sholo.Web.Security/Analysis/RequestAnalyzer.cs
/// <summary>
/// Perform analysis of the FormsAuthenticationTicket supplied
/// </summary>
/// <param name="cookieAnalysis">The result of the FormsAuthenticationCookie analysis</param>
/// <param name="enforceServerAuthenticationTicketValidation">Indicates whether to enforce UserAuthenticationTicket validation</param>
/// <returns>A FormsAuthenticationTicketAnalysis object containing the results of the analysis</returns>
Perform analysis of the FormsAuthenticationTicket supplied
Perform analysis of the FormsAuthenticationTicket supplied
public static FormsAuthenticationTicketAnalysis AnalyzeFormsAuthenticationTicket(FormsAuthenticationCookieAnalysis cookieAnalysis, bool enforceServerAuthenticationTicketValidation, RequestLifecyclePhase? phase)
        {
            FormsAuthenticationTicketAnalysis analysis = new FormsAuthenticationTicketAnalysis();
            FormsAuthenticationTicket ticket = cookieAnalysis.GetFormsAuthenticationTicket();
            analysis.TicketExists = (ticket != null);
            if (analysis.TicketExists)
            {
                if (cookieAnalysis.HasValue && ticket != null)
                {
                    DateTime netFramework2ReleaseDate = new DateTime(2006, 1, 22);
                    analysis.FormsAuthenticationTicket = ticket;
                    analysis.TicketExists = true;
                    analysis.CookiePathMatches = (ticket.CookiePath == FormsAuthentication.FormsCookiePath);
                    analysis.HasUserData = (!string.IsNullOrEmpty(ticket.UserData));
                    analysis.IsExpired = ticket.Expired || ticket.Expiration.CompareTo(DateTime.Now) < 0;
                    analysis.IsIssueDateValid = (ticket.IssueDate.CompareTo(netFramework2ReleaseDate) > 0);
                    analysis.IsNameValid = (!string.IsNullOrEmpty(ticket.Name)); 
                    analysis.HasUserData = !string.IsNullOrEmpty(ticket.UserData);
                    analysis.IsPersistenceValid = true; 
                    string guid = null;
                    if (ticket.UserData != null && ticket.UserData.Length == UserAuthentication.HashAlgorithmStringLength + UserAuthentication.GuidStringLength + 1 && ticket.UserData[UserAuthentication.HashAlgorithmStringLength] == ';')
                    {
                        string[] parts = ticket.UserData.Split(';');
                        if (parts.Length == 2)
                        {
                            string hash = parts[0];
                            analysis.UserDataContainsHash = true;
                            for (int i = 0; i < hash.Length; i++)
                            {
                                if (!((hash[i] >= 0x30 && hash[i] <= 0x39) 
                                        || (hash[i] >= 0x61 && hash[i] <= 0x66))) 
                                {
                                    analysis.UserDataContainsHash = false;
                                    break;
                                }
                            }
                            if (analysis.UserDataContainsHash)
                            {
                                analysis.TicketHash = hash;
                                string actualHash = UserAuthentication.CalculateFormsAuthTicketHash(ticket);
                                analysis.IsUserDataHashValid = (hash == actualHash);
                            }
                            guid = parts[1];
                            try
                            {
                                #pragma warning disable 168
                                Guid testGuidCreation = new Guid(guid);
                                #pragma warning restore 168
                                analysis.ServerKey = parts[1];
                                analysis.UserDataContainsServerAuthenticationTicketKey = true;
                            }
                            catch (FormatException)
                            {
                                analysis.UserDataContainsServerAuthenticationTicketKey = false;
                            }
                            catch (OverflowException)
                            {
                                analysis.UserDataContainsServerAuthenticationTicketKey = false;
                            }
                            catch (ArgumentNullException)
                            {
                                analysis.UserDataContainsServerAuthenticationTicketKey = false;
                            }
                        }
                        else
                        {
                            analysis.UserDataContainsHash = false;
                            analysis.UserDataContainsServerAuthenticationTicketKey = false;
                        }
                    }
                    else
                    {
                        analysis.UserDataContainsHash = false;
                        analysis.UserDataContainsServerAuthenticationTicketKey = false;
                    }
                    if (!string.IsNullOrEmpty(guid))
                    {
                        UserAuthenticationTicket serverAuthenticationTicket = UserAuthentication.Provider.GetTicket(guid);
                        if (serverAuthenticationTicket != null)
                        {
                            analysis.UserDataServerAuthenticationTicketKeyFound = true;
                            analysis.SetServerAuthenticationTicket(serverAuthenticationTicket);
                        }
                        else
                        {
                            analysis.UserDataServerAuthenticationTicketKeyFound = false;
                        }
                    }
                    else
                    {
                        analysis.UserDataServerAuthenticationTicketKeyFound = false;
                    }
                    analysis.IsVersionValid = (ticket.Version == 2);
                    analysis.IsValid =
                        analysis.TicketExists &&
                        analysis.CookiePathMatches &&
                        !analysis.IsExpired &&
                        analysis.IsIssueDateValid &&
                        analysis.IsNameValid &&
                        analysis.IsPersistenceValid &&
                        analysis.IsVersionValid;
                    if (!analysis.IsValid)
                    {
                        analysis.IsMalicious =
                            !analysis.CookiePathMatches ||
                            !analysis.IsPersistenceValid ||
                            !analysis.IsIssueDateValid ||
                            !analysis.IsNameValid ||
                            !analysis.IsVersionValid;
                    }
                }
                else
                {
                    analysis.IsValid = false;
                    analysis.IsMalicious = false;
                }
            }
            else
            {
                analysis.IsValid = false;
                analysis.IsMalicious = false;
            }
            return analysis;
        }
public static FormsAuthenticationTicketAnalysis AnalyzeFormsAuthenticationTicket ( FormsAuthenticationCookieAnalysis cookieAnalysis , bool enforceServerAuthenticationTicketValidation , RequestLifecyclePhase ? phase ) { FormsAuthenticationTicketAnalysis analysis = new FormsAuthenticationTicketAnalysis ( ) ; FormsAuthenticationTicket ticket = cookieAnalysis . GetFormsAuthenticationTicket ( ) ; analysis . TicketExists = ( ticket != null ) ; if ( analysis . TicketExists ) { if ( cookieAnalysis . HasValue && ticket != null ) { DateTime netFramework2ReleaseDate = new DateTime ( 2006 , 1 , 22 ) ; analysis . FormsAuthenticationTicket = ticket ; analysis . TicketExists = true ; analysis . CookiePathMatches = ( ticket . CookiePath == FormsAuthentication . FormsCookiePath ) ; analysis . HasUserData = ( ! string . IsNullOrEmpty ( ticket . UserData ) ) ; analysis . IsExpired = ticket . Expired || ticket . Expiration . CompareTo ( DateTime . Now ) < 0 ; analysis . IsIssueDateValid = ( ticket . IssueDate . CompareTo ( netFramework2ReleaseDate ) > 0 ) ; analysis . IsNameValid = ( ! string . IsNullOrEmpty ( ticket . Name ) ) ; analysis . HasUserData = ! string . IsNullOrEmpty ( ticket . UserData ) ; analysis . IsPersistenceValid = true ; string guid = null ; if ( ticket . UserData != null && ticket . UserData . Length == UserAuthentication . HashAlgorithmStringLength + UserAuthentication . GuidStringLength + 1 && ticket . UserData [ UserAuthentication . HashAlgorithmStringLength ] == ' ' ) { string [ ] parts = ticket . UserData . Split ( ' ' ) ; if ( parts . Length == 2 ) { string hash = parts [ 0 ] ; analysis . UserDataContainsHash = true ; for ( int i = 0 ; i < hash . Length ; i ++ ) { if ( ! ( ( hash [ i ] >= 0x30 && hash [ i ] <= 0x39 ) || ( hash [ i ] >= 0x61 && hash [ i ] <= 0x66 ) ) ) { analysis . UserDataContainsHash = false ; break ; } } if ( analysis . UserDataContainsHash ) { analysis . TicketHash = hash ; string actualHash = UserAuthentication . CalculateFormsAuthTicketHash ( ticket ) ; analysis . IsUserDataHashValid = ( hash == actualHash ) ; } guid = parts [ 1 ] ; try { pragma warning disable 168 Guid testGuidCreation = new Guid ( guid ) ; pragma warning restore 168 analysis . ServerKey = parts [ 1 ] ; analysis . UserDataContainsServerAuthenticationTicketKey = true ; } catch ( FormatException ) { analysis . UserDataContainsServerAuthenticationTicketKey = false ; } catch ( OverflowException ) { analysis . UserDataContainsServerAuthenticationTicketKey = false ; } catch ( ArgumentNullException ) { analysis . UserDataContainsServerAuthenticationTicketKey = false ; } } else { analysis . UserDataContainsHash = false ; analysis . UserDataContainsServerAuthenticationTicketKey = false ; } } else { analysis . UserDataContainsHash = false ; analysis . UserDataContainsServerAuthenticationTicketKey = false ; } if ( ! string . IsNullOrEmpty ( guid ) ) { UserAuthenticationTicket serverAuthenticationTicket = UserAuthentication . Provider . GetTicket ( guid ) ; if ( serverAuthenticationTicket != null ) { analysis . UserDataServerAuthenticationTicketKeyFound = true ; analysis . SetServerAuthenticationTicket ( serverAuthenticationTicket ) ; } else { analysis . UserDataServerAuthenticationTicketKeyFound = false ; } } else { analysis . UserDataServerAuthenticationTicketKeyFound = false ; } analysis . IsVersionValid = ( ticket . Version == 2 ) ; analysis . IsValid = analysis . TicketExists && analysis . CookiePathMatches && ! analysis . IsExpired && analysis . IsIssueDateValid && analysis . IsNameValid && analysis . IsPersistenceValid && analysis . IsVersionValid ; if ( ! analysis . IsValid ) { analysis . IsMalicious = ! analysis . CookiePathMatches || ! analysis . IsPersistenceValid || ! analysis . IsIssueDateValid || ! analysis . IsNameValid || ! analysis . IsVersionValid ; } } else { analysis . IsValid = false ; analysis . IsMalicious = false ; } } else { analysis . IsValid = false ; analysis . IsMalicious = false ; } return analysis ; }
Perform analysis of the FormsAuthenticationTicket supplied
Perform analysis of the FormsAuthenticationTicket supplied
// && ticket.Name == ContextInformation.ThreadCurrentPrincipalIdentityName && ticket.Name == ContextInformation.UserIdentityName); /* TODO: See how to check this in FormsAuthentication */ /* 0-9 */ /* || (hash[i] >= 0x41 && hash[i] <= 0x46)      A-F   (lowercase only!) */ /* a-f */ /*
                        &&
                        (!enforceServerAuthenticationTicketValidation || analysis.HasUserData) &&
                        (!enforceServerAuthenticationTicketValidation || analysis.UserDataContainsHash) &&
                        (!enforceServerAuthenticationTicketValidation || analysis.IsUserDataHashValid) &&
                        (!enforceServerAuthenticationTicketValidation || analysis.UserDataContainsServerAuthenticationTicketKey) &&
                        (!enforceServerAuthenticationTicketValidation || analysis.UserDataServerAuthenticationTicketKeyFound) &&
                        (!enforceServerAuthenticationTicketValidation || UserAuthenticationTicket != null);
                    */ /*
                        if (!analysis.IsMalicious && enforceServerAuthenticationTicketValidation && !isEndRequest)
                        {
                            analysis.IsMalicious = 
                                !analysis.HasUserData || 
                                !analysis.UserDataContainsHash || 
                                !analysis.IsUserDataHashValid || 
                                !analysis.UserDataContainsServerAuthenticationTicketKey;
                        }
                        */
A FormsAuthenticationTicketAnalysis object containing the results of the analysis
A FormsAuthenticationTicketAnalysis object containing the results of the analysis
cookieAnalysis
FormsAuthenticationCookieAnalysis
The result of the FormsAuthenticationCookie analysis
The result of the FormsAuthenticationCookie analysis
enforceServerAuthenticationTicketValidation
bool
Indicates whether to enforce UserAuthenticationTicket validation
Indicates whether to enforce UserAuthenticationTicket validation
phase
RequestLifecyclePhase?