/// <summary> /// Ctor /// </summary> /// <param name="parameterName"></param> /// <param name="parameterValue"></param> /// <param name="location"></param> /// <param name="test"></param> public TestJob(string parameterName, string parameterValue, RequestLocation location, CustomTestDef test) { // TODO: Complete member initialization _parameterName = parameterName; _parameterValue = parameterValue; _requestLocation = location; _testDef = test; }
/// <summary> /// Validates a single test payload /// </summary> /// <param name="rawRequest"></param> /// <param name="rawResponse"></param> /// <param name="requestUri"></param> /// <param name="parameterName"></param> /// <param name="entityId"></param> /// <param name="testDef"></param> /// <param name="mutatedRequest"></param> /// <param name="testResponse"></param> /// <returns></returns> public bool ValidateSingleTest(string rawRequest, string rawResponse, Uri requestUri, string parameterName, string entityId, CustomTestDef testDef, string mutatedRequest, string testResponse) { bool found = false; if (!String.IsNullOrWhiteSpace(testResponse) && !String.IsNullOrWhiteSpace(testDef.Exclusion) && Utils.IsMatch(testResponse, testDef.Exclusion)) { return(false); //this type of response was excluded from testing } if (String.IsNullOrWhiteSpace(testResponse) && testDef.Validation.Contains(TIMEOUT_FUNC)) { found = true; } if (!found && !String.IsNullOrWhiteSpace(testResponse) && !String.IsNullOrWhiteSpace(testDef.Validation)) { string matchFilePath = null; IEnumerable <string> matchList = null; if (!String.IsNullOrWhiteSpace(testDef.Validation) && testDef.Validation.StartsWith("$match_file")) { string[] parts = testDef.Validation.Split(new char[1] { '=' }, 2); if (parts.Length == 2) { matchFilePath = parts[1]; if (_matchFiles.ContainsKey(matchFilePath)) { matchList = _matchFiles[matchFilePath]; } else { //cache the matches matchList = File.ReadLines(matchFilePath); _matchFiles[matchFilePath] = matchList; } } } string validation = String.Empty; if (matchList != null) { foreach (string match in matchList) { if (!String.IsNullOrWhiteSpace(match) && testResponse.Contains(match) && !rawResponse.Contains(match)) { found = true; validation = Regex.Escape(match); break; } } } else { validation = testDef.Validation.Replace("$entity_id", entityId); string testResponsePartToValidate = testResponse; string origResponsePartToValidate = rawResponse; if (validation.StartsWith("$body=") || validation.StartsWith("$header=")) { //parse responses HttpResponseInfo testRespInfo = new HttpResponseInfo(testResponse); HttpResponseInfo origRespInfo = new HttpResponseInfo(rawResponse); //process the body directive if (validation.StartsWith("$body=")) { testResponsePartToValidate = testRespInfo.ResponseBody.ToString(); origResponsePartToValidate = origRespInfo.ResponseBody.ToString(); validation = validation.Substring("$body=".Length); } else if (validation.StartsWith("$header=")) { testResponsePartToValidate = testRespInfo.ResponseHeadString; origResponsePartToValidate = origRespInfo.ResponseBody.ToString(); validation = validation.Substring("$header=".Length); } } found = Utils.IsMatch(testResponsePartToValidate, validation); if (found) { //make sure raw response does not contain the validation found &= !Utils.IsMatch(origResponsePartToValidate, validation); } } } if (found) { _testController.Log("ISSUE FOUND for test '{0}'", testDef.Name); List <string> mutatedRequestList = new List <string>(); mutatedRequestList.Add(mutatedRequest); List <string> testResponseList = new List <string>(); testResponseList.Add(testResponse); _testController.HandleIssueFound(rawRequest, rawResponse, requestUri, testDef.Type, parameterName, mutatedRequestList, testResponseList, testDef.Validation, ""); } return(found); }
/// <summary> /// Validates a response and inserts a vulnerability /// </summary> /// <param name="rawRequest"></param> /// <param name="rawResponse"></param> /// <param name="requestUri"></param> /// <param name="parameterName"></param> /// <param name="entityId"></param> /// <param name="testDef"></param> /// <param name="payload"></param> /// <param name="mutatedRequestList"></param> /// <param name="testResponseList"></param> public bool ValidateTest(string rawRequest, string rawResponse, Uri requestUri, string parameterName, string entityId, CustomTestDef testDef, List <string> mutatedRequestList, List <string> testResponseList) { string validation = testDef.Validation.Trim(); if (String.IsNullOrWhiteSpace(validation)) { return(false); //this is a callback test } bool found = false; bool isMultiValidationRule = IsMultiValidationRule(validation); if (!isMultiValidationRule) { for (int idx = 0; idx < mutatedRequestList.Count; idx++) { string mutatedRequest = mutatedRequestList[idx]; string testResponse = testResponseList[idx]; found |= ValidateSingleTest(rawRequest, rawResponse, requestUri, parameterName, entityId, testDef, mutatedRequest, testResponse); } } else { if (validation.StartsWith(JAVASCRIPT_FUNCTION_TAG)) { found = RunJavaScriptValidation(validation, testResponseList); } else if (validation.StartsWith(TAUTOLOGY_VERIFICATION_FUNC)) { if (testResponseList != null && testResponseList.Count % 3 == 0) { int encodingsCount = testResponseList.Count / 3; for (int i = 0; i < encodingsCount && !found; i++) { int first = i; int second = i + encodingsCount; int third = i + 2 * encodingsCount; double firstAndThirdSimilarity = ASESimilarityAlgorithm.CalculateSimilarity(testResponseList[first], testResponseList[third]); double firstAndSecondSimilarity = ASESimilarityAlgorithm.CalculateSimilarity(testResponseList[first], testResponseList[second]); found = firstAndThirdSimilarity - firstAndSecondSimilarity > 0.2; //first and third are more similar than first and second if (found) { var newMutatedRequestList = new List <string>(); var newTestResponseList = new List <string>(); newMutatedRequestList.Add(mutatedRequestList[first]); newMutatedRequestList.Add(mutatedRequestList[second]); newMutatedRequestList.Add(mutatedRequestList[third]); newTestResponseList.Add(testResponseList[first]); newTestResponseList.Add(testResponseList[second]); newTestResponseList.Add(testResponseList[third]); mutatedRequestList = newMutatedRequestList; testResponseList = newTestResponseList; } } } else { _testController.Log("INCORRECT NUMBER OF PAYLOADS FOR TAUTOLOGY VERIFICATION (MUST BE DIVISIBLE WITH 3)"); } } if (found) { for (int i = 0; i < mutatedRequestList.Count; i++) { _testController.Log("MULTI-VALIDATION rule match on entity '{0}', test '{1}'", parameterName, testDef.Name); } _testController.HandleIssueFound(rawRequest, rawResponse, requestUri, testDef.Type, parameterName, mutatedRequestList, testResponseList, validation, ""); } } return(found); }