/// <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 VisitForEach(ForEachStatementSyntax node, ExecutionState state) { var variableState = VisitExpression(node.Expression, state); switch (node.ControlVariable) { case VariableDeclaratorSyntax variableDeclarator: var names = variableDeclarator.Names; foreach (var name in names) { state.AddNewValue(ResolveIdentifier(name.Identifier), variableState); } break; case IdentifierNameSyntax identifierName: state.AddNewValue(ResolveIdentifier(identifierName.Identifier), variableState); break; default: throw new ArgumentException(nameof(node.ControlVariable)); } return(VisitNode(node.Expression, state)); }
/// <summary> /// Entry point that visit the method statements. /// </summary> /// <param name="node"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitMethodDeclaration(MethodDeclarationSyntax node, ExecutionState state) { foreach (ParameterSyntax parameter in node.ParameterList.Parameters) { state.AddNewValue(ResolveIdentifier(parameter.Identifier), new VariableState(parameter, VariableTaint.Tainted)); } if (node.Body == null) { return(new VariableState(node, VariableTaint.Unknown)); } foreach (StatementSyntax statement in node.Body.Statements) { VisitNode(statement, state); foreach (var ext in Extensions) { ext.VisitStatement(statement, state); } } //The state return is irrelevant because it is not use. return(new VariableState(node, VariableTaint.Unknown)); }
/// <summary> /// Evaluate expression that contains a list of assignment. /// </summary> /// <param name="declaration"></param> /// <param name="state"></param> private VariableState VisitVariableDeclaration(VariableDeclarationSyntax declaration, ExecutionState state) { var lastState = new VariableState(declaration, VariableTaint.Unknown); foreach (var variable in declaration.Variables) { VariableState varState; if (variable.Initializer != null) { varState = VisitExpression(variable.Initializer.Value, state); var type = state.AnalysisContext.SemanticModel.GetTypeInfo(variable.Initializer.Value); if (type.ConvertedType != null && (type.ConvertedType.IsType("System.String") || type.ConvertedType.IsValueType)) { var copy = new VariableState(varState.Node, varState.Taint, varState.Value); foreach (var property in varState.PropertyStates) { copy.AddProperty(property.Key, property.Value); } varState = copy; } } else { varState = new VariableState(variable, VariableTaint.Constant); } state.AddNewValue(ResolveIdentifier(variable.Identifier), varState); lastState = varState; } return(lastState); }
private void TaintParameters(MethodBlockBaseSyntax node, ParameterListSyntax parameterList, ExecutionState state) { foreach (ParameterSyntax parameter in parameterList.Parameters) { state.AddNewValue(ResolveIdentifier(parameter.Identifier.Identifier), new VariableState(parameter, VariableTaint.Tainted)); } }
/// <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 VisitForEach(ForEachStatementSyntax node, ExecutionState state) { var variableState = VisitExpression(node.Expression, state); var names = ((VariableDeclaratorSyntax)node.ControlVariable).Names; foreach (var name in names) { state.AddNewValue(ResolveIdentifier(name.Identifier), variableState); } return(VisitNode(node.Expression, state)); }
/// <summary> /// Entry point that visits the method statements. /// </summary> /// <param name="node"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitMethodDeclaration(BaseMethodDeclarationSyntax node, ExecutionState state) { foreach (ParameterSyntax parameter in node.ParameterList.Parameters) { state.AddNewValue(ResolveIdentifier(parameter.Identifier), new VariableState(parameter, VariableTaint.Tainted)); } if (node.Body == null) { return(new VariableState(node, VariableTaint.Unknown)); } return(VisitBlock(node.Body, state)); }
private VariableState VisitCollectionRangeVariable(CollectionRangeVariableSyntax collectionRangeVariableSyntax, ExecutionState state) { var expressionState = VisitExpression(collectionRangeVariableSyntax.Expression, state); var fromSymbol = SyntaxNodeHelper.GetSymbol(collectionRangeVariableSyntax.Expression, state.AnalysisContext.SemanticModel); if (fromSymbol != null) { switch (fromSymbol) { case IPropertySymbol propertyFromSymbol when propertyFromSymbol.Type.IsTaintType(ProjectConfiguration.Behavior): case IFieldSymbol fieldFromSymbol when fieldFromSymbol.Type.IsTaintType(ProjectConfiguration.Behavior): expressionState = new VariableState(collectionRangeVariableSyntax, VariableTaint.Tainted); break; } } state.AddNewValue(ResolveIdentifier(collectionRangeVariableSyntax.Identifier.Identifier), expressionState); return(expressionState); }
/// <summary> /// Evaluate expression that contains a list of assignment. /// </summary> /// <param name="declaration"></param> /// <param name="state"></param> private VariableState VisitVariableDeclaration(VariableDeclarationSyntax declaration, ExecutionState state) { var lastState = new VariableState(declaration, VariableTaint.Unknown); foreach (var variable in declaration.Variables) { var identifier = variable.Identifier; var initializer = variable.Initializer; if (initializer == null) { continue; } EqualsValueClauseSyntax equalsClause = initializer; VariableState varState = VisitExpression(equalsClause.Value, state); //varState.SetType(lastState.type); state.AddNewValue(ResolveIdentifier(identifier), varState); lastState = varState; } // return(lastState); }
private VariableState VisitForEach(ForEachStatementSyntax node, ExecutionState state) { state.AddNewValue(ResolveIdentifier(node.Identifier), VisitExpression(node.Expression, state)); return(VisitNode(node.Statement, state)); }
/// <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("BodySyntax"); if (syntaxNodeProperty == null) { return(new VariableState(expression, VariableTaint.Unknown)); } var syntaxNode = (CSharpSyntaxNode)syntaxNodeProperty.GetValue(prop.GetMethod); switch (syntaxNode) { case BlockSyntax 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)); case ArrowExpressionClauseSyntax arrowSyntax: // 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(VisitExpression(arrowSyntax.Expression, state)); } return(new VariableState(expression, VariableTaint.Unknown)); } 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) { var value = ResolveIdentifier(expression.Identifier); if (state.VariableStates.TryGetValue(value, out var varState)) { return(varState); } var symbol = state.GetSymbol(expression); if (symbol == null) { return(new VariableState(expression, VariableTaint.Unknown)); } if (symbol is IFieldSymbol field) { if (field.IsConst) { return(new VariableState(expression, VariableTaint.Constant)); } if (!field.IsReadOnly) { return(new VariableState(expression, VariableTaint.Unknown)); } switch (field.ToDisplayString(SymbolExtensions.SymbolDisplayFormat)) { case "System.String.Empty": case "System.IntPtr.Zero": return(new VariableState(expression, VariableTaint.Constant)); } return(new VariableState(expression, VariableTaint.Unknown)); } if (symbol is 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("BodySyntax"); if (syntaxNodeProperty == null) { return(new VariableState(expression, VariableTaint.Unknown)); } var syntaxNode = (CSharpSyntaxNode)syntaxNodeProperty.GetValue(prop.GetMethod); if (syntaxNode is BlockSyntax 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)); } if (syntaxNode is ArrowExpressionClauseSyntax arrowSyntax) { // 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(VisitExpression(arrowSyntax.Expression, state)); } return(new VariableState(expression, VariableTaint.Unknown)); } return(new VariableState(expression, VariableTaint.Unknown)); }