public void VerifyValidRuleDetection() { var validRule = new AsaRule("Regular Rule") { Expression = "0 AND 1", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.EQ) { Label = "0", Data = new List <string>() { "TestPath2" } }, new Clause("IsExecutable", OPERATION.EQ) { Label = "1", Data = new List <string>() { "True" } } } }; var analyzer = new AsaAnalyzer(); Assert.IsTrue(analyzer.IsRuleValid(validRule)); validRule = new AsaRule("Extraneous Parenthesis") { Expression = "(0 AND 1)", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.EQ) { Label = "0", Data = new List <string>() { "TestPath2" } }, new Clause("IsExecutable", OPERATION.EQ) { Label = "1", Data = new List <string>() { "True" } } } }; Assert.IsTrue(analyzer.IsRuleValid(validRule)); validRule = new AsaRule("Deeply Nested Expression") { Expression = "(0 AND 1) OR (2 XOR (3 AND (4 NAND 5)) OR 6)", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.EQ) { Label = "0", Data = new List <string>() { "TestPath2" } }, new Clause("IsExecutable", OPERATION.EQ) { Label = "1", Data = new List <string>() { "True" } }, new Clause("IsExecutable", OPERATION.IS_NULL) { Label = "2" }, new Clause("IsExecutable", OPERATION.IS_NULL) { Label = "3" }, new Clause("IsExecutable", OPERATION.IS_NULL) { Label = "4" }, new Clause("IsExecutable", OPERATION.IS_NULL) { Label = "5" }, new Clause("IsExecutable", OPERATION.IS_NULL) { Label = "6" } } }; Assert.IsTrue(analyzer.IsRuleValid(validRule)); validRule = new AsaRule("StringsForClauseLabels") { Expression = "FOO AND BAR OR BA$_*", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("IsExecutable", OPERATION.IS_NULL) { Label = "FOO" }, new Clause("IsExecutable", OPERATION.IS_NULL) { Label = "BAR" }, new Clause("IsExecutable", OPERATION.IS_NULL) { Label = "BA$_*" } } }; Assert.IsTrue(analyzer.IsRuleValid(validRule)); }
public void VerifyCustomRuleValidation() { var RuleName = "CustomRuleValidation"; var supportedCustomOperation = new AsaRule(RuleName) { Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.CUSTOM) { CustomOperation = "FOO", Data = new List <string>() { TestPathOne } }, } }; var unsupportedCustomOperation = new AsaRule(RuleName) { Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.CUSTOM) { CustomOperation = "BAR", Data = new List <string>() { TestPathOne } }, } }; var analyzer = new AsaAnalyzer(); analyzer.CustomOperationValidationDelegate = parseFooOperations; IEnumerable <Violation> parseFooOperations(Rule r, Clause c) { switch (c.CustomOperation) { case "FOO": if (!c.Data.Any()) { yield return(new Violation("FOO Operation expects data", r, c)); } break; default: yield return(new Violation($"{c.CustomOperation} is unexpected", r, c)); break; } }; Assert.IsTrue(analyzer.IsRuleValid(supportedCustomOperation)); Assert.IsFalse(analyzer.IsRuleValid(unsupportedCustomOperation)); }
public void VerifyInvalidRuleDetection() { var invalidRule = new AsaRule("Unbalanced Parentheses") { Expression = "( 0 AND 1", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.EQ) { Label = "0", Data = new List <string>() { "TestPath2" } }, new Clause("IsExecutable", OPERATION.EQ) { Label = "1", Data = new List <string>() { "True" } } } }; var analyzer = new AsaAnalyzer(); Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("ClauseInParenthesesLabel") { Expression = "WITH(PARENTHESIS)", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "WITH(PARENTHESIS)" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("CharactersBetweenParentheses") { Expression = "(W(I", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "W(I" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("CharactersBeforeOpenParentheses") { Expression = "W(I", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "W(I" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("CharactersBetweenClosedParentheses") { Expression = "(0 AND W)I)", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "W)I" }, new Clause("Path", OPERATION.IS_NULL) { Label = "0" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("CharactersAfterClosedParentheses") { Expression = "0 AND W)I", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "W)I" }, new Clause("Path", OPERATION.IS_NULL) { Label = "0" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("MultipleConsecutiveNots") { Expression = "0 AND NOT NOT 1", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "1" }, new Clause("Path", OPERATION.IS_NULL) { Label = "0" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("CloseParenthesesWithNot") { Expression = "(0 AND NOT) 1", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "1" }, new Clause("Path", OPERATION.IS_NULL) { Label = "0" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("WhiteSpaceLabel") { Expression = "0 AND ", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "0" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("InvalidOperator") { Expression = "0 XAND 1", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "1" }, new Clause("Path", OPERATION.IS_NULL) { Label = "0" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("InvalidNotOperator") { Expression = "0 NOT AND 1", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "1" }, new Clause("Path", OPERATION.IS_NULL) { Label = "0" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("EndsWithOperator") { Expression = "0 AND", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "0" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("UnusedLabel") { Expression = "0", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "1" }, new Clause("Path", OPERATION.IS_NULL) { Label = "0" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("MissingLabel") { Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "0" }, new Clause("Path", OPERATION.IS_NULL) } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("ExpressionRequiresLabels") { Expression = "0 AND 1", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL), new Clause("Path", OPERATION.IS_NULL) } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("OutOfOrder") { Expression = "0 1 AND", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.EQ) { Label = "0", Data = new List <string>() { "TestPath2" } }, new Clause("IsExecutable", OPERATION.IS_TRUE) { Label = "1" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("StartWithOperator") { Expression = "OR 0 1", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.EQ) { Label = "0", Data = new List <string>() { "TestPath2" } }, new Clause("IsExecutable", OPERATION.EQ) { Label = "1", Data = new List <string>() { "True" } } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("Case Sensitivity") { Expression = "Variable", Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.IS_NULL) { Label = "VARIABLE" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); invalidRule = new AsaRule("OPERATION.Custom without CustomOperation") { Target = "FileSystemObject", Flag = ANALYSIS_RESULT_TYPE.FATAL, Clauses = new List <Clause>() { new Clause("Path", OPERATION.CUSTOM) { Label = "VARIABLE" } } }; Assert.IsFalse(analyzer.IsRuleValid(invalidRule)); }