internal bool IsUniqueToScan(Request Req, List <Request> ScannedRequests, bool IgnoreUrl) { int DuplicateNamesMatchCounter = 0; foreach (Request RR in ScannedRequests) { if (!Req.Method.Equals(RR.Method)) { continue; } if (Req.HasBody != RR.HasBody) { continue; } if (Req.UrlPathParts.Count != RR.UrlPathParts.Count) { continue; } if (Req.Query.Count != RR.Query.Count) { continue; } if (Req.HasBody) { if (Req.Body.Count != RR.Body.Count) { continue; } } if (Req.URLPath.Equals(RR.URLPath)) { List <string> ReqQueryNames = Req.Query.GetNames(); List <string> RRQueryNames = RR.Query.GetNames(); if (AreListValuesSame(ReqQueryNames, RRQueryNames)) { if (PromptUser) { List <string> MismatchedParameters = GetMismatchedQueryParameterNames(Req, RR); if (IsAnyQueryParameterUnique(MismatchedParameters)) { return(true); } else if (AreAllQueryParametersNonUnique(MismatchedParameters)) { if (!Req.HasBody) { return(false); } } else { StringBuilder Message = new StringBuilder(); Message.Append("<i<b>><i<cg>>Request A:<i</cg>><i</b>><i<br>>"); Message.Append(" "); Message.Append(RR.Method); Message.Append(" "); Message.Append(RR.UrlPath); Message.Append("?"); foreach (string Name in RR.Query.GetNames()) { foreach (string Value in RR.Query.GetAll(Name)) { if (MismatchedParameters.Contains(Name)) { Message.Append("<i<hlo>>"); } Message.Append(Name); Message.Append("="); Message.Append(Value); if (MismatchedParameters.Contains(Name)) { Message.Append("<i</hlo>>"); } Message.Append("&"); } } if (Message.ToString().EndsWith("&")) { Message.Remove(Message.Length - 1, 1); } Message.Append("<i<br>>"); Message.Append("<i<b>><i<cg>>Request B:<i</cg>><i</b>><i<br>>"); Message.Append(" "); Message.Append(Req.Method); Message.Append(" "); Message.Append(Req.UrlPath); Message.Append("?"); foreach (string Name in Req.Query.GetNames()) { foreach (string Value in Req.Query.GetAll(Name)) { if (MismatchedParameters.Contains(Name)) { Message.Append("<i<hlo>>"); } Message.Append(Name); Message.Append("="); Message.Append(Value); if (MismatchedParameters.Contains(Name)) { Message.Append("<i</hlo>>"); } Message.Append("&"); } } if (Message.ToString().EndsWith("&")) { Message.Remove(Message.Length - 1, 1); } Message.Append("<i<br>>"); Message.Append("<i<br>>"); Message.Append(@"Request A has been sent for scanning already. Request B is being considered for scanning.<i<br>> Request A & Request B have the same Query parameter names but some parameters have different values.<i<br>> If Request B can be considered a duplicate of A and not scanned then just hit 'Submit'.<i<br>> If the values of some the mis-matched parameters makes Request B unique then select those Query Paramters from the provided list and then hit 'Submit'"); List <int> AskUserResponse = AskUser.ForList("Duplicate Scan Item Check", Message.ToString(), "Scan Request B", "Don't scan Request B", "Scan Request B and set these parameters as unique", MismatchedParameters); List <string> UniqueParams = new List <string>(); for (int i = 2; i < AskUserResponse.Count; i++) { UniqueParams.Add(MismatchedParameters[AskUserResponse[i]]); } if (UniqueParams.Count > 0 || AskUserResponse[0] == 1) { UniqueQueryParameters.AddRange(UniqueParams); return(true); } else { NonUniqueQueryParameters.AddRange(MismatchedParameters); if (!Req.HasBody) { return(false); } } } } else { if (!Req.HasBody) { DuplicateNamesMatchCounter++; if (DuplicateNamesMatchCounter > 3) { return(false); } } } } else { continue; } if (Req.HasBody) { List <string> ReqBodyNames = Req.Body.GetNames(); List <string> RRBodyNames = RR.Body.GetNames(); if (AreListValuesSame(ReqBodyNames, RRBodyNames)) { if (PromptUser) { List <string> MismatchedParameters = GetMismatchedBodyParameterNames(Req, RR); if (IsAnyBodyParameterUnique(MismatchedParameters)) { return(true); } else if (AreAllBodyParametersNonUnique(MismatchedParameters)) { return(false); } else { StringBuilder Message = new StringBuilder(); Message.Append("<i<b>><i<cg>>Request A:<i</cg>><i</b>><i<br>>"); Message.Append(" "); Message.Append(RR.Method); Message.Append(" "); Message.Append(RR.Url); Message.Append("<i<br>><i<br>>"); Message.Append(" "); foreach (string Name in RR.Body.GetNames()) { foreach (string Value in RR.Body.GetAll(Name)) { if (MismatchedParameters.Contains(Name)) { Message.Append("<i<hlo>>"); } Message.Append(Name); Message.Append("="); Message.Append(Value); if (MismatchedParameters.Contains(Name)) { Message.Append("<i</hlo>>"); } Message.Append("&"); } } if (Message.ToString().EndsWith("&")) { Message.Remove(Message.Length - 1, 1); } Message.Append("<i<br>>"); Message.Append("<i<br>>"); Message.Append("<i<b>><i<cg>>Request B:<i</cg>><i</b>><i<br>>"); Message.Append(" "); Message.Append(Req.Method); Message.Append(" "); Message.Append(Req.Url); Message.Append("<i<br>><i<br>>"); Message.Append(" "); foreach (string Name in Req.Body.GetNames()) { foreach (string Value in Req.Body.GetAll(Name)) { if (MismatchedParameters.Contains(Name)) { Message.Append("<i<hlo>>"); } Message.Append(Name); Message.Append("="); Message.Append(Value); if (MismatchedParameters.Contains(Name)) { Message.Append("<i</hlo>>"); } Message.Append("&"); } } if (Message.ToString().EndsWith("&")) { Message.Remove(Message.Length - 1, 1); } Message.Append("<i<br>>"); Message.Append("<i<br>>"); Message.Append(@"Request A has been sent for scanning already. Request B is being considered for scanning.<i<br>> Request A & Request B have the same Body parameter names but some parameters have different values.<i<br>> If Request B can be considered a duplicate of A and not scanned then just hit 'Submit'.<i<br>> If the values of some the mis-matched parameters makes Request B unique then select those Body Paramters from the provided list and then hit 'Submit'"); List <int> AskUserResponse = AskUser.ForList("Duplicate Scan Item Check", Message.ToString(), "Scan Request B", "Don't scan Request B", "Scan Request B and set these parameters as unique", MismatchedParameters); List <string> UniqueParams = new List <string>(); for (int i = 2; i < AskUserResponse.Count; i++) { UniqueParams.Add(MismatchedParameters[AskUserResponse[i]]); } if (UniqueParams.Count > 0 || AskUserResponse[0] == 1) { UniqueBodyParameters.AddRange(UniqueParams); return(true); } else { NonUniqueBodyParameters.AddRange(MismatchedParameters); return(false); } } } else { DuplicateNamesMatchCounter++; if (DuplicateNamesMatchCounter > 3) { return(false); } } } else { continue; } } } else { if (!PromptUser) { return(true); } if (IgnoreUrl) { return(false); } if (!(Req.File.Equals("") && RR.File.Equals(""))) { continue; } List <string> PathPartMatch = new List <string>(); List <string> ReqUrlPathParts = new List <string>(Req.UrlPathParts); List <string> RRUrlPathParts = new List <string>(RR.UrlPathParts); List <string> MatchUrlPathParts = new List <string>(); List <string> MatchedParts = new List <string>(); List <string> ReqAMismatchedParts = new List <string>(); List <string> ReqBMismatchedParts = new List <string>(); bool LastMatch = true; for (int i = 0; i < ReqUrlPathParts.Count; i++) { if (LastMatch) { if (ReqUrlPathParts[i].Equals(RRUrlPathParts[i])) { MatchUrlPathParts.Add(ReqUrlPathParts[i]); MatchedParts.Add(ReqUrlPathParts[i]); } else { LastMatch = false; MatchUrlPathParts.Add("*"); ReqAMismatchedParts.Add(RRUrlPathParts[i]); ReqBMismatchedParts.Add(ReqUrlPathParts[i]); } } else { MatchUrlPathParts.Add("*"); ReqAMismatchedParts.Add(RRUrlPathParts[i]); ReqBMismatchedParts.Add(ReqUrlPathParts[i]); } } if (MatchedParts.Count == 0) { continue; } List <string> MatchUrlPathSignatures = UniqueUrlSignatureGenerator(MatchedParts, ReqBMismatchedParts); string MatchUrlPathSignature = "/" + String.Join("/", MatchUrlPathParts.ToArray()) + "/"; if (IsUrlPathSignatureUnique(MatchUrlPathSignatures)) { return(true); } if (IsUrlPathSignatureNonUnique(MatchUrlPathSignatures)) { return(false); } StringBuilder Message = new StringBuilder(); Message.Append("<i<b>><i<cg>>Request A:<i</cg>><i</b>><i<br>>"); Message.Append(" "); Message.Append(RR.Method); Message.Append(" "); foreach (string Part in MatchedParts) { Message.Append("/"); Message.Append(Part); } foreach (string Part in ReqAMismatchedParts) { Message.Append("/"); Message.Append("<i<hlo>>"); Message.Append(Part); Message.Append("<i</hlo>>"); } if (RR.Url.EndsWith("/")) { Message.Append("/"); } Message.Append("<i<br>>"); Message.Append("<i<br>>"); Message.Append("<i<b>><i<cg>>Request B:<i</cg>><i</b>><i<br>>"); Message.Append(" "); Message.Append(Req.Method); Message.Append(" "); foreach (string Part in MatchedParts) { Message.Append("/"); Message.Append(Part); } foreach (string Part in ReqBMismatchedParts) { Message.Append("/"); Message.Append("<i<hlo>>"); Message.Append(Part); Message.Append("<i</hlo>>"); } if (Req.Url.EndsWith("/")) { Message.Append("/"); } Message.Append("<i<br>>"); Message.Append("<i<br>>"); Message.Append(@"Request A has been sent for scanning already. Request B is being considered for scanning.<i<br>> Request A & Request B have the same starting URL but some sections of the URL differ, this could probably be a case of URL re-writing.<i<br>> If Request B can be considered a duplicate of A and not scanned then just hit 'Submit'.<i<br>> If some sections of the URL path make Request B unique then select those sections from the provided list and then hit 'Submit'"); List <int> AskUserResponse = AskUser.ForList("Duplicate Scan Item Check", Message.ToString(), "Scan Request B", "Don't scan Request B", "Scan Request B and set these parameters as unique", ReqBMismatchedParts); List <int> UniquePathPartPositions = new List <int>(); for (int i = 2; i < AskUserResponse.Count; i++) { UniquePathPartPositions.Add(AskUserResponse[i]); } if (UniquePathPartPositions.Count == 0 && AskUserResponse[1] == 1) { NonUniqueUrlParameters.Add(MatchUrlPathSignature); return(false); } else { if (UniquePathPartPositions.Count > 0) { List <string> NewSignatureList = new List <string>(MatchedParts); for (int ii = 0; ii < ReqBMismatchedParts.Count; ii++) { if (UniquePathPartPositions.Contains(ii)) { NewSignatureList.Add(ReqBMismatchedParts[ii]); } else { NewSignatureList.Add("*"); } } NonUniqueUrlParameters.Add("/" + string.Join("/", NewSignatureList.ToArray()) + "/"); } return(true); } } } return(true); }