private void AnalyzeNodeForXslCompiledTransformLoad(SyntaxNodeAnalysisContext context) { SyntaxNode node = context.Node; SemanticModel model = context.SemanticModel; IMethodSymbol methodSymbol = _syntaxNodeHelper.GetCalleeMethodSymbol(node, model); if (SecurityDiagnosticHelpers.IsXslCompiledTransformLoad(methodSymbol, _xmlTypes)) { bool isSecureResolver; bool isSecureSettings; bool isSetInBlock; int xmlResolverIndex = SecurityDiagnosticHelpers.GetXmlResolverParameterIndex(methodSymbol, _xmlTypes); int xsltSettingsIndex = SecurityDiagnosticHelpers.GetXsltSettingsParameterIndex(methodSymbol, _xmlTypes); // Overloads with no XmlResolver and XstlSettings specified are secure since they all have folowing behavior: // 1. An XmlUrlResolver with no user credentials is used to process any xsl:import or xsl:include elements. // 2. The document() function is disabled. // 3. Embedded scripts are not supported. if (xmlResolverIndex >= 0 && xsltSettingsIndex >= 0) { IEnumerable <SyntaxNode> argumentExpressionNodes = _syntaxNodeHelper.GetInvocationArgumentExpressionNodes(node); SyntaxNode resolverNode = argumentExpressionNodes.ElementAt(xmlResolverIndex); isSecureResolver = SyntaxNodeHelper.NodeHasConstantValueNull(resolverNode, model) || SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(resolverNode).Type, _xmlTypes); SyntaxNode settingsNode = argumentExpressionNodes.ElementAt(xsltSettingsIndex); ISymbol settingsSymbol = SyntaxNodeHelper.GetSymbol(settingsNode, model); // 1. pass null or XsltSettings.Default as XsltSetting : secure if (settingsSymbol == null || SecurityDiagnosticHelpers.IsXsltSettingsDefaultProperty(settingsSymbol as IPropertySymbol, _xmlTypes)) { isSetInBlock = true; isSecureSettings = true; } // 2. XsltSettings.TrustedXslt : insecure else if (SecurityDiagnosticHelpers.IsXsltSettingsTrustedXsltProperty(settingsSymbol as IPropertySymbol, _xmlTypes)) { isSetInBlock = true; isSecureSettings = false; } // 3. check xsltSettingsEnvironments, if IsScriptDisabled && IsDocumentFunctionDisabled then secure, else insecure else if (_xsltSettingsEnvironments.TryGetValue(settingsSymbol, out XsltSettingsEnvironment env)) { isSetInBlock = false; isSecureSettings = env.IsDocumentFunctionDisabled && env.IsScriptDisabled; } //4. symbol for settings is not found => passed in without any change => assume insecure else { isSetInBlock = true; isSecureSettings = false; } if (!isSecureSettings && !isSecureResolver) { LocalizableResourceString message = SecurityDiagnosticHelpers.GetLocalizableResourceString( isSetInBlock ? nameof(MicrosoftNetFrameworkAnalyzersResources.XslCompiledTransformLoadInsecureConstructedMessage) : nameof(MicrosoftNetFrameworkAnalyzersResources.XslCompiledTransformLoadInsecureInputMessage), SecurityDiagnosticHelpers.GetNonEmptyParentName(node, model, context.CancellationToken) ); context.ReportDiagnostic( Diagnostic.Create( RuleDoNotUseInsecureXSLTScriptExecution, node.GetLocation(), message ) ); } } } }
private void AnalyzeNodeForXsltSettings(SyntaxNodeAnalysisContext context) { SyntaxNode node = context.Node; SemanticModel model = context.SemanticModel; SyntaxNode lhs = _syntaxNodeHelper.GetAssignmentLeftNode(node); SyntaxNode rhs = _syntaxNodeHelper.GetAssignmentRightNode(node); if (lhs == null || rhs == null) { return; } ISymbol lhsSymbol = SyntaxNodeHelper.GetSymbol(lhs, model); if (lhsSymbol == null) { return; } IMethodSymbol rhsMethodSymbol = _syntaxNodeHelper.GetCalleeMethodSymbol(rhs, model); IPropertySymbol rhsPropertySymbol = SyntaxNodeHelper.GetCalleePropertySymbol(rhs, model); if (SecurityDiagnosticHelpers.IsXsltSettingsCtor(rhsMethodSymbol, _xmlTypes)) { XsltSettingsEnvironment env = new XsltSettingsEnvironment(); _xsltSettingsEnvironments[lhsSymbol] = env; env.XsltSettingsSymbol = lhsSymbol; env.XsltSettingsDefinitionSymbol = rhsMethodSymbol; env.XsltSettingsDefinition = node; env.EnclosingConstructSymbol = _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model); //default both properties are disbled env.IsDocumentFunctionDisabled = true; env.IsScriptDisabled = true; // XsltSettings Constructor (Boolean, Boolean) if (rhsMethodSymbol.Parameters.Any()) { IEnumerable <SyntaxNode> argumentExpressionNodes = _syntaxNodeHelper.GetObjectCreationArgumentExpressionNodes(rhs); env.IsDocumentFunctionDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(argumentExpressionNodes.ElementAt(0), model); env.IsScriptDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(argumentExpressionNodes.ElementAt(1), model); } foreach (SyntaxNode arg in _syntaxNodeHelper.GetObjectInitializerExpressionNodes(rhs)) { SyntaxNode argLhs = _syntaxNodeHelper.GetAssignmentLeftNode(arg); SyntaxNode argRhs = _syntaxNodeHelper.GetAssignmentRightNode(arg); ISymbol argLhsSymbol = SyntaxNodeHelper.GetSymbol(argLhs, model); // anything other than a constant false is treated as true if (SecurityDiagnosticHelpers.IsXsltSettingsEnableDocumentFunctionProperty(argLhsSymbol as IPropertySymbol, _xmlTypes)) { env.IsDocumentFunctionDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(argRhs, model); } else if (SecurityDiagnosticHelpers.IsXsltSettingsEnableScriptProperty(argLhsSymbol as IPropertySymbol, _xmlTypes)) { env.IsScriptDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(argRhs, model); } } } else if (SecurityDiagnosticHelpers.IsXsltSettingsDefaultProperty(rhsPropertySymbol, _xmlTypes)) { XsltSettingsEnvironment env = new XsltSettingsEnvironment(); _xsltSettingsEnvironments[lhsSymbol] = env; env.XsltSettingsSymbol = lhsSymbol; env.XsltSettingsDefinitionSymbol = rhsPropertySymbol; env.XsltSettingsDefinition = node; env.EnclosingConstructSymbol = _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model); env.IsDocumentFunctionDisabled = true; env.IsScriptDisabled = true; } else if (SecurityDiagnosticHelpers.IsXsltSettingsTrustedXsltProperty(rhsPropertySymbol, _xmlTypes)) { XsltSettingsEnvironment env = new XsltSettingsEnvironment(); _xsltSettingsEnvironments[lhsSymbol] = env; env.XsltSettingsSymbol = lhsSymbol; env.XsltSettingsDefinitionSymbol = rhsPropertySymbol; env.XsltSettingsDefinition = node; env.EnclosingConstructSymbol = _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model); } else { bool isXlstSettingsEnableDocumentFunctionProperty = SecurityDiagnosticHelpers.IsXsltSettingsEnableDocumentFunctionProperty(lhsSymbol as IPropertySymbol, _xmlTypes); bool isXlstSettingsEnableScriptProperty = SecurityDiagnosticHelpers.IsXsltSettingsEnableScriptProperty(lhsSymbol as IPropertySymbol, _xmlTypes); if (isXlstSettingsEnableDocumentFunctionProperty || isXlstSettingsEnableScriptProperty) { SyntaxNode lhsExpressionNode = _syntaxNodeHelper.GetMemberAccessExpressionNode(lhs); if (lhsExpressionNode == null) { return; } ISymbol lhsExpressionSymbol = SyntaxNodeHelper.GetSymbol(lhsExpressionNode, model); if (lhsExpressionSymbol == null) { return; } if (!_xsltSettingsEnvironments.TryGetValue(lhsExpressionSymbol, out XsltSettingsEnvironment env)) { env = new XsltSettingsEnvironment { XsltSettingsSymbol = lhsExpressionSymbol }; _xsltSettingsEnvironments[lhsExpressionSymbol] = env; } if (isXlstSettingsEnableDocumentFunctionProperty) { env.IsDocumentFunctionDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(rhs, model); } else if (isXlstSettingsEnableScriptProperty) { env.IsScriptDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(rhs, model); } } } }