private IReadOnlyDictionary <int, PostCondition> GetPostConditions(MethodBehavior behavior, bool isExtensionMethod, ArgumentListSyntax argList, ExecutionState state) { if (behavior.Conditions == null) { return(behavior.PostConditions); } foreach (var condition in behavior.Conditions) { if (CheckPrecondition(condition.If, isExtensionMethod, argList, state)) { return(condition.Then); } } return(behavior.PostConditions); }
/// <summary> /// Identifier name include variable name. /// </summary> /// <param name="expression"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitIdentifierName(IdentifierNameSyntax expression, ExecutionState state) { var value = ResolveIdentifier(expression.Identifier); if (state.VariableStates.TryGetValue(value, out var varState)) { return(varState); } var symbol = state.GetSymbol(expression); switch (symbol) { case null: return(new VariableState(expression, VariableTaint.Unknown)); case IFieldSymbol field: if (field.IsConst) { return(new VariableState(expression, VariableTaint.Constant)); } if (!field.IsReadOnly) { return(new VariableState(expression, VariableTaint.Unknown)); } switch (field.GetTypeName()) // todo: move out to config of readonly values, that are constant in fact { case "System.String.Empty": case "System.IntPtr.Zero": case "System.IO.Path.AltDirectorySeparatorChar": case "System.IO.Path.DirectorySeparatorChar": case "System.IO.Path.InvalidPathChars": case "System.IO.Path.PathSeparator": case "System.IO.Path.VolumeSeparatorChar": return(new VariableState(expression, VariableTaint.Constant)); } return(new VariableState(expression, VariableTaint.Unknown)); case IPropertySymbol prop: if (prop.IsVirtual || prop.IsOverride || prop.IsAbstract) { return(new VariableState(expression, VariableTaint.Unknown)); } // TODO: Use public API var syntaxNodeProperty = prop.GetMethod.GetType().GetTypeInfo().BaseType.GetTypeInfo().GetDeclaredProperty("Syntax"); var syntaxNode = (VisualBasicSyntaxNode)syntaxNodeProperty?.GetValue(prop.GetMethod); switch (syntaxNode) { case null: return(new VariableState(expression, VariableTaint.Unknown)); case AccessorBlockSyntax blockSyntax: // Recursion prevention: set the value into the map if we'll get back resolving it while resolving it dependency state.AddNewValue(value, new VariableState(expression, VariableTaint.Unknown)); return(VisitBlock(blockSyntax, state)); } return(new VariableState(expression, VariableTaint.Unknown)); } return(new VariableState(expression, VariableTaint.Unknown)); }
private VariableState VisitArrayCreation(SyntaxNode node, CollectionInitializerSyntax arrayInit, ExecutionState state) { var finalState = new VariableState(node, VariableTaint.Safe); if (arrayInit == null) { return(finalState); } foreach (var ex in arrayInit.Initializers) { var exprState = VisitExpression(ex, state); finalState = finalState.Merge(exprState); } return(finalState); }
private VariableState VisitAssignmentStatement(AssignmentStatementSyntax node, ExecutionState state) { return(VisitAssignment(node, node.Left, node.Right, state)); }
private VariableState VisitObjectCreation(ObjectCreationExpressionSyntax node, ExecutionState state) { VariableState finalState = VisitInvocationAndCreation(node, node.ArgumentList, state); foreach (SyntaxNode child in node.DescendantNodes()) { if (child is NamedFieldInitializerSyntax namedFieldInitializerSyntax) { finalState = finalState.Merge(VisitNamedFieldInitializer(namedFieldInitializerSyntax, state)); } else { Logger.Log(child.GetText().ToString().Trim() + " -> " + finalState); } } return(finalState); }
/// <summary> /// Unwrap /// </summary> /// <param name="declaration"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitLocalDeclaration(LocalDeclarationStatementSyntax declaration, ExecutionState state) { foreach (var i in declaration.Declarators) { return(VisitVariableDeclaration(i, state)); } return(new VariableState(declaration, VariableTaint.Unknown)); }
private VariableState VisitExpression(ExpressionSyntax expression, ExecutionState state) { // TODO: Review other expression types that are unique to VB. // TODO: Write tests to cover all these. switch (expression) { case InvocationExpressionSyntax invocationExpressionSyntax: return(VisitMethodInvocation(invocationExpressionSyntax, state)); case ObjectCreationExpressionSyntax objectCreationExpressionSyntax: return(VisitObjectCreation(objectCreationExpressionSyntax, state)); case LiteralExpressionSyntax _: return(new VariableState(expression, VariableTaint.Constant)); case IdentifierNameSyntax identifierNameSyntax: return(VisitIdentifierName(identifierNameSyntax, state)); case BinaryExpressionSyntax binaryExpressionSyntax: return(VisitBinaryExpression(binaryExpressionSyntax, state)); case MemberAccessExpressionSyntax memberAccessExpressionSyntax: return(VisitExpression(memberAccessExpressionSyntax.Name, state)); case ArrayCreationExpressionSyntax arrayCreationExpressionSyntax: return(VisitArrayCreation(arrayCreationExpressionSyntax, arrayCreationExpressionSyntax.Initializer, state)); case CollectionInitializerSyntax collectionInitializerSyntax: return(VisitArrayCreation(collectionInitializerSyntax, collectionInitializerSyntax, state)); case TypeOfExpressionSyntax typeOfExpressionSyntax: return(new VariableState(typeOfExpressionSyntax, VariableTaint.Safe)); case GetTypeExpressionSyntax getTypeExpressionSyntax: return(new VariableState(getTypeExpressionSyntax, VariableTaint.Safe)); case TernaryConditionalExpressionSyntax ternaryConditionalExpressionSyntax: { VisitExpression(ternaryConditionalExpressionSyntax.Condition, state); var finalState = new VariableState(ternaryConditionalExpressionSyntax, VariableTaint.Safe); var whenTrueState = VisitExpression(ternaryConditionalExpressionSyntax.WhenTrue, state); finalState = finalState.Merge(whenTrueState); var whenFalseState = VisitExpression(ternaryConditionalExpressionSyntax.WhenFalse, state); finalState = finalState.Merge(whenFalseState); return(finalState); } case QueryExpressionSyntax queryExpressionSyntax: return(new VariableState(queryExpressionSyntax, VariableTaint.Unknown)); case DirectCastExpressionSyntax directCastExpressionSyntax: return(VisitExpression(directCastExpressionSyntax.Expression, state)); case CTypeExpressionSyntax cTypeExpressionSyntax: return(VisitExpression(cTypeExpressionSyntax.Expression, state)); } Logger.Log("Unsupported expression " + expression.GetType() + " (" + expression + ")"); return(new VariableState(expression, VariableTaint.Unknown)); }
/// <summary> /// Identifier name include variable name. /// </summary> /// <param name="expression"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitIdentifierName(IdentifierNameSyntax expression, ExecutionState state) { return(ResolveVariableState(expression, state)); }
private VariableState VisitMemberAccessExpression(MemberAccessExpressionSyntax expression, ExecutionState state) { return(ResolveVariableState(expression, state)); }
private VariableState VisitAssignmentStatement(AssignmentStatementSyntax node, ExecutionState state) { var assigmentState = VisitAssignment(node, node.Left, node.Right, state); return(MergeVariableState(node.Left, assigmentState, state)); }
private VariableState VisitNamedFieldInitializer(NamedFieldInitializerSyntax node, ExecutionState state, VariableState currentScope) { var assigmentState = VisitAssignment(node, node.Name, node.Expression, state); return(MergeVariableState(node.Name, assigmentState, state, currentScope)); }
private VariableState VisitMemberAccessExpression(MemberAccessExpressionSyntax expression, ExecutionState state) { var varState = VisitIdentifierName(expression, state); if (varState.Taint == VariableTaint.Constant || expression.Expression == null) { return(varState); } var expressionState = VisitExpression(expression.Expression, state); varState.MergeTaint(expressionState.Taint); return(varState); }
/// <summary> /// Logic for each method invocation (including constructor) /// The argument list is required because <code>InvocationExpressionSyntax</code> and /// <code>ObjectCreationExpressionSyntax</code> do not share a common interface. /// </summary> private VariableState VisitInvocationAndCreation(ExpressionSyntax node, ArgumentListSyntax argList, ExecutionState state, VariableTaint?initialTaint = null, VariableState memberVariableState = null) { var symbol = state.GetSymbol(node); if (symbol == null) { return(new VariableState(node, initialTaint ?? VariableTaint.Unknown)); } var methodSymbol = symbol as IMethodSymbol; bool isExtensionMethod = methodSymbol?.ReducedFrom != null; var behavior = symbol.GetMethodBehavior(ProjectConfiguration.Behavior); IReadOnlyDictionary <int, PostCondition> postConditions = null; if (behavior != null) { postConditions = GetPostConditions(behavior, isExtensionMethod, argList, state); } PostCondition returnPostCondition = null; postConditions?.TryGetValue(-1, out returnPostCondition); VariableState returnState = initialTaint != null && !symbol.IsStatic ? new VariableState(node, initialTaint.Value) : new VariableState(node, argList?.Arguments.Count > 0 && behavior != null ? VariableTaint.Unset : VariableTaint.Unknown); var argCount = argList?.Arguments.Count; var argumentStates = argCount.HasValue && argCount.Value > 0 && (postConditions?.Any(c => c.Key != -1 && (c.Value.Taint != 0ul || c.Value.TaintFromArguments.Any())) == true || methodSymbol != null && methodSymbol.Parameters.Any(x => x.RefKind != RefKind.None)) ? new VariableState[argCount.Value] : null; for (var i = 0; i < argList?.Arguments.Count; i++) { var argument = argList.Arguments[i]; var argumentState = VisitExpression(argument.Expression, state); if (argumentStates != null) { argumentStates[i] = argumentState; } #if DEBUG Logger.Log(symbol.ContainingType + "." + symbol.Name + " -> " + argumentState); #endif var adjustedArgumentIdx = isExtensionMethod ? i + 1 : i; if (behavior != null) { if ((argumentState.Taint & (ProjectConfiguration.AuditMode ? VariableTaint.Tainted | VariableTaint.Unknown : VariableTaint.Tainted)) != 0) { //If the current parameter can be injected. if (behavior.InjectableArguments.TryGetValue(adjustedArgumentIdx, out var injectableArgument) && (injectableArgument.RequiredTaintBits & (ulong)argumentState.Taint) != injectableArgument.RequiredTaintBits) { var newRule = LocaleUtil.GetDescriptor(injectableArgument.Locale); var diagnostic = Diagnostic.Create(newRule, argument.Expression.GetLocation(), GetMethodName(node), (i + 1).ToNthString()); state.AnalysisContext.ReportDiagnostic(diagnostic); } } else if (argumentState.Taint == VariableTaint.Constant) { if (behavior.InjectableArguments.TryGetValue(adjustedArgumentIdx, out var injectableArgument) && injectableArgument.Not && (injectableArgument.RequiredTaintBits & (ulong)argumentState.Taint) != 0ul) { var newRule = LocaleUtil.GetDescriptor(injectableArgument.Locale); var diagnostic = Diagnostic.Create(newRule, argument.Expression.GetLocation(), GetMethodName(node), (i + 1).ToNthString()); state.AnalysisContext.ReportDiagnostic(diagnostic); } } } var argumentToSearch = adjustedArgumentIdx; if (methodSymbol != null && i >= methodSymbol.Parameters.Length && methodSymbol.Parameters[methodSymbol.Parameters.Length - 1].IsParams) { argumentToSearch = isExtensionMethod ? methodSymbol.Parameters.Length : methodSymbol.Parameters.Length - 1; } if (returnPostCondition == null || returnPostCondition.TaintFromArguments.Contains(argumentToSearch)) { returnState.MergeTaint(argumentState.Taint); } //TODO: taint all objects passed as arguments //if (argument.Expression is IdentifierNameSyntax identifierNameSyntax) //{ // var argumentType = state.AnalysisContext.SemanticModel.GetTypeInfo(argument.Expression).Type; // if (argumentType.IsReferenceType && // argumentType.IsType("System.String")) // string is immutable // { // state.MergeValue(ResolveIdentifier(identifierNameSyntax.Identifier), // argumentState.Merge(new VariableState(argument, VariableTaint.Unknown))); // } //} } if (returnPostCondition != null) { returnState.ApplyTaint(returnPostCondition.Taint); } if (argumentStates != null) { for (var i = 0; i < argList.Arguments.Count; i++) { var adjustedPostConditionIdx = isExtensionMethod ? i + 1 : i; if (postConditions != null && postConditions.TryGetValue(adjustedPostConditionIdx, out var postCondition)) { foreach (var argIdx in postCondition.TaintFromArguments) { var adjustedArgumentIdx = isExtensionMethod ? argIdx + 1 : argIdx; argumentStates[adjustedPostConditionIdx].MergeTaint(argumentStates[adjustedArgumentIdx].Taint); } argumentStates[adjustedPostConditionIdx].ApplyTaint(postCondition.Taint); } else if (methodSymbol != null) { if (i >= methodSymbol.Parameters.Length) { if (!methodSymbol.Parameters[methodSymbol.Parameters.Length - 1].IsParams) { throw new IndexOutOfRangeException(); } } else if (methodSymbol.Parameters[i].RefKind != RefKind.None) { argumentStates[i].MergeTaint(returnState.Taint); } } } } if (memberVariableState != null && methodSymbol != null && methodSymbol.ReturnsVoid && !methodSymbol.IsStatic && methodSymbol.Parameters.All(x => x.RefKind == RefKind.None)) { memberVariableState.MergeTaint(returnState.Taint); } //Additional analysis by extension foreach (var ext in Extensions) { ext.VisitInvocationAndCreation(node, argList, state, ProjectConfiguration); } return(returnState); }
private bool CheckPrecondition(IReadOnlyDictionary <int, object> condition, bool isExtensionMethod, ArgumentListSyntax argList, ExecutionState state) { for (var i = 0; i < argList?.Arguments.Count; i++) { var argument = argList.Arguments[i]; var adjustedArgumentIdx = isExtensionMethod ? i + 1 : i; if (!condition.TryGetValue(adjustedArgumentIdx, out var preconditionArgumentValue)) { continue; } var calculatedArgumentValue = state.AnalysisContext.SemanticModel.GetConstantValue(argument.Expression); if (calculatedArgumentValue.HasValue && calculatedArgumentValue.Value.Equals(preconditionArgumentValue)) { continue; } return(false); } return(true); }
public virtual void VisitInvocationAndCreation(VBSyntax.ExpressionSyntax node, VBSyntax.ArgumentListSyntax argList, ExecutionState state) { }
private VariableState ResolveVariableState(ExpressionSyntax expression, ExecutionState state) { var varState = GetVariableState(expression, state); if (varState != null) { return(varState); } var symbol = state.GetSymbol(expression); switch (symbol) { case null: return(new VariableState(expression, VariableTaint.Unknown)); case IFieldSymbol field: if (field.IsConst) { return(new VariableState(expression, VariableTaint.Constant)); } if (!field.IsReadOnly) { return(new VariableState(expression, VariableTaint.Unknown)); } var contantFields = ConfigurationManager.Instance.GetProjectConfiguration(state.AnalysisContext.Options.AdditionalFiles) .ConstantFields; if (contantFields.Contains(field.GetTypeName())) { return(new VariableState(expression, VariableTaint.Constant)); } return(new VariableState(expression, VariableTaint.Unknown)); case IPropertySymbol prop: if (prop.IsVirtual || prop.IsOverride || prop.IsAbstract) { return(new VariableState(expression, VariableTaint.Unknown)); } // TODO: Use public API var syntaxNodeProperty = prop.GetMethod.GetType().GetTypeInfo().BaseType.GetTypeInfo().GetDeclaredProperty("Syntax"); var syntaxNode = (VisualBasicSyntaxNode)syntaxNodeProperty?.GetValue(prop.GetMethod); switch (syntaxNode) { case null: return(new VariableState(expression, VariableTaint.Unknown)); case AccessorBlockSyntax blockSyntax: // Recursion prevention: set the value into the map if we'll get back resolving it while resolving it dependency MergeVariableState(expression, new VariableState(expression, VariableTaint.Unknown), state); return(VisitBlock(blockSyntax, state)); } return(new VariableState(expression, VariableTaint.Unknown)); } return(new VariableState(expression, VariableTaint.Unknown)); }
/// <summary> /// Statement are all segment separate by semi-colon. /// </summary> /// <param name="node"></param> /// <param name="state"></param> private VariableState VisitNode(SyntaxNode node, ExecutionState state) { //Logger.Log(node.GetType().ToString()); switch (node) { case LocalDeclarationStatementSyntax localDeclaration: return(VisitLocalDeclaration(localDeclaration, state)); case VariableDeclaratorSyntax variableDeclaration: return(VisitVariableDeclaration(variableDeclaration, state)); case AssignmentStatementSyntax assignment: return(VisitAssignmentStatement(assignment, state)); case ExpressionStatementSyntax expressionStatement: return(VisitExpressionStatement(expressionStatement, state)); case ExpressionSyntax expression: return(VisitExpression(expression, state)); case MethodBlockSyntax methodBlock: return(VisitMethodDeclaration(methodBlock, methodBlock.SubOrFunctionStatement.ParameterList, state)); case ConstructorBlockSyntax constructorBlockSyntax: return(VisitMethodDeclaration(constructorBlockSyntax, constructorBlockSyntax.SubNewStatement.ParameterList, state)); case PropertyBlockSyntax propertyBlockSyntax: { foreach (var accessor in propertyBlockSyntax.Accessors) { VisitBlock(accessor, state); } return(new VariableState(node, VariableTaint.Unknown)); } case ReturnStatementSyntax returnStatementSyntax: if (returnStatementSyntax.Expression == null) { return(new VariableState(node, VariableTaint.Unknown)); } return(VisitExpression(returnStatementSyntax.Expression, state)); case ForEachStatementSyntax forEachSyntax: return(VisitForEach(forEachSyntax, state)); } foreach (var n in node.ChildNodes()) { VisitNode(n, state); } var isBlockStatement = node is IfStatementSyntax || node is ForStatementSyntax; if (!isBlockStatement) { Logger.Log("Unsupported statement " + node.GetType() + " (" + node + ")"); } return(new VariableState(node, VariableTaint.Unknown)); }
/// <summary> /// Entry point that visits the method statements. /// </summary> private VariableState VisitMethodDeclaration(BaseMethodDeclarationSyntax node, ExecutionState state) { if (ProjectConfiguration.AuditMode) { TaintParameters(node, state); } else { var symbol = state.AnalysisContext.SemanticModel.GetDeclaredSymbol(node); if (symbol != null) { if (symbol is IMethodSymbol methodSymbol && methodSymbol.IsStatic && methodSymbol.Name == "Main") { TaintParameters(node, state); } else if (symbol.IsTaintEntryPoint(ProjectConfiguration.TaintEntryPoints)) { TaintParameters(node, state); } } }
/// <summary> /// Evaluate expression that contains a list of assignment. /// </summary> /// <param name="declaration"></param> /// <param name="state"></param> private VariableState VisitVariableDeclaration(VariableDeclaratorSyntax declaration, ExecutionState state) { var lastState = new VariableState(declaration, VariableTaint.Unknown); foreach (var variable in declaration.Names) { var identifier = variable.Identifier; var initializer = declaration.Initializer; if (initializer != null) { EqualsValueSyntax equalsClause = initializer; VariableState varState = VisitExpression(equalsClause.Value, state); //varState.SetType(lastState.type); state.AddNewValue(ResolveIdentifier(identifier), varState); lastState = varState; } if (declaration.AsClause is AsNewClauseSyntax asNewClauseSyntax) { VariableState varState = VisitExpression(asNewClauseSyntax.NewExpression, state); state.AddNewValue(ResolveIdentifier(identifier), varState); lastState = varState; } } return(lastState); }
private VariableState VisitBlock(BlockSyntax node, ExecutionState state) { var lastState = new VariableState(node, VariableTaint.Unknown); return(VisitStatements(node.Statements, state, lastState)); }
/// <summary> /// Logic for each method invocation (including constructor) /// The argument list is required because <code>InvocationExpressionSyntax</code> and /// <code>ObjectCreationExpressionSyntax</code> do not share a common interface. /// </summary> /// <param name="node"></param> /// <param name="argList"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitInvocationAndCreation(ExpressionSyntax node, ArgumentListSyntax argList, ExecutionState state, VariableState?initialVariableState = null) { var symbol = state.GetSymbol(node); if (symbol == null) { return(new VariableState(node, VariableTaint.Unknown)); } var behavior = BehaviorRepo.GetMethodBehavior(symbol); var returnState = initialVariableState.HasValue && !symbol.IsStatic ? initialVariableState.Value : new VariableState(node, behavior?.TaintFromArguments?.Any() == true ? VariableTaint.Safe : VariableTaint.Unknown); for (var i = 0; i < argList?.Arguments.Count; i++) { var argument = argList.Arguments[i]; var argumentState = VisitExpression(argument.GetExpression(), state); Logger.Log(symbol.ContainingType + "." + symbol.Name + " -> " + argumentState); if (behavior == null) { continue; } //If the API is at risk if ((argumentState.Taint == VariableTaint.Tainted || argumentState.Taint == VariableTaint.Unknown) && //Tainted values //If the current parameter can be injected. Array.Exists(behavior.InjectablesArguments, element => element == i)) { var newRule = LocaleUtil.GetDescriptor(behavior.LocaleInjection); var diagnostic = Diagnostic.Create(newRule, node.GetLocation(), GetMethodName(node), (i + 1).ToNthString()); state.AnalysisContext.ReportDiagnostic(diagnostic); } else if (argumentState.Taint == VariableTaint.Constant && //Hard coded value //If the current parameter is a password Array.Exists(behavior.PasswordArguments, element => element == i)) { var newRule = LocaleUtil.GetDescriptor(behavior.LocalePassword); var diagnostic = Diagnostic.Create(newRule, node.GetLocation(), GetMethodName(node), (i + 1).ToNthString()); state.AnalysisContext.ReportDiagnostic(diagnostic); } else if (Array.Exists(behavior.TaintFromArguments, element => element == i)) { returnState = returnState.Merge(argumentState); } //TODO: taint all objects passed as arguments } //Additional analysis by extension foreach (var ext in Extensions) { ext.VisitInvocationAndCreation(node, argList, state); } return(returnState); }
private VariableState VisitStatements(SyntaxList <StatementSyntax> statements, ExecutionState state, VariableState lastState) { foreach (StatementSyntax statement in statements) { var statementState = VisitNode(statement, state); lastState = statementState; foreach (var ext in Extensions) { ext.VisitStatement(statement, state, ProjectConfiguration); } } return(lastState); }
private VariableState VisitNamedFieldInitializer(NamedFieldInitializerSyntax node, ExecutionState state) { return(VisitAssignment(node, node.Name, node.Expression, state)); }
private VariableState VisitAssignment(VisualBasicSyntaxNode node, ExpressionSyntax leftExpression, ExpressionSyntax rightExpression, ExecutionState state) { var leftSymbol = state.GetSymbol(leftExpression); MethodBehavior behavior = null; if (leftSymbol != null) { behavior = leftSymbol.GetMethodBehavior(state.AnalysisContext.Options.AdditionalFiles); } var variableState = VisitExpression(rightExpression, state); //Additional analysis by extension foreach (var ext in Extensions) { ext.VisitAssignment(node, state, behavior, leftSymbol, variableState); } if (leftSymbol != null) { var rightTypeSymbol = state.AnalysisContext.SemanticModel.GetTypeInfo(rightExpression).Type; if (rightTypeSymbol == null) { return(new VariableState(rightExpression, VariableTaint.Unknown)); } var leftTypeSymbol = state.AnalysisContext.SemanticModel.GetTypeInfo(leftExpression).Type; if (!state.AnalysisContext.SemanticModel.Compilation.ClassifyConversion(rightTypeSymbol, leftTypeSymbol).Exists) { return(new VariableState(rightExpression, VariableTaint.Unknown)); } } IdentifierNameSyntax parentIdentifierSyntax = GetParentIdentifier(leftExpression); if (parentIdentifierSyntax != null) { state.MergeValue(ResolveIdentifier(parentIdentifierSyntax.Identifier), variableState); } if (behavior != null && //Injection behavior.IsInjectableField && variableState.Taint != VariableTaint.Constant && //Skip safe values variableState.Taint != VariableTaint.Safe) { var newRule = LocaleUtil.GetDescriptor(behavior.LocaleInjection, "title_assignment"); var diagnostic = Diagnostic.Create(newRule, node.GetLocation()); state.AnalysisContext.ReportDiagnostic(diagnostic); } if (behavior != null && //Known Password API behavior.IsPasswordField && variableState.Taint == VariableTaint.Constant) //Only constant { var newRule = LocaleUtil.GetDescriptor(behavior.LocalePassword, "title_assignment"); var diagnostic = Diagnostic.Create(newRule, node.GetLocation()); state.AnalysisContext.ReportDiagnostic(diagnostic); } //TODO: taint the variable being assigned. return(variableState); }
/// <summary> /// Combine the state of the two operands. Binary expression include concatenation. /// </summary> /// <param name="expression"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitBinaryExpression(BinaryExpressionSyntax expression, ExecutionState state) { VariableState left = VisitExpression(expression.Left, state); VariableState right = VisitExpression(expression.Right, state); return(left.Merge(right)); }
public virtual void VisitEnd(SyntaxNode node, ExecutionState state) { }
private VariableState VisitExpressionStatement(ExpressionStatementSyntax node, ExecutionState state) { return(VisitExpression(node.Expression, state)); //Simply unwrap the expression }
public virtual void VisitStatement(VBSyntax.StatementSyntax node, ExecutionState state) { }
/// <summary> /// Entry point that visits the method statements. /// </summary> /// <param name="node"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitMethodDeclaration(MethodBlockBaseSyntax node, ParameterListSyntax parameterList, ExecutionState state) { foreach (ParameterSyntax parameter in parameterList.Parameters) { state.AddNewValue(ResolveIdentifier(parameter.Identifier.Identifier), new VariableState(parameter, VariableTaint.Tainted)); } return(VisitBlock(node, state)); }
private VariableState VisitObjectCreation(ObjectCreationExpressionSyntax node, ExecutionState state) { VariableState finalState = VisitInvocationAndCreation(node, node.ArgumentList, state); foreach (SyntaxNode child in node.DescendantNodes()) { if (child is AssignmentExpressionSyntax assignmentExpressionSyntax) { var assignmentState = VisitAssignment(assignmentExpressionSyntax, state); MergeVariableState(assignmentExpressionSyntax.Left, assignmentState, state, finalState); } else { #if DEBUG Logger.Log(child.GetText().ToString().Trim() + " -> " + finalState); #endif } } return(finalState); }