Fortify清理规则并不能清除所有内容

时间:2017-10-11 21:29:52

标签: c# fortify

我的团队最近开始在我们的.NET代码库(C#6和VB.NET)上使用Fortify静态代码分析器(版本17.10.0 156),并且在报告的误报数量方面遇到了一些痛苦。对于任何给定的问题,我们不知道它是否是一个误报,而我们不希望任何实际问题在混乱中迷失。

我们有一个带有方法ReadEmbeddedSql的实用程序库,它从嵌入在程序集中的资源中提取sql以执行。 Fortify标记执行使用Sql Injection漏洞从此方法返回的sql的任何OracleCommand(来自Oracle.ManagedDataAccess.Client)。 在命令上设置sql时,无论是通过构造函数还是通过CommandText属性,都会报告此漏洞。

如果在本地程序集中定义了ReadEmbeddedSql方法,则不会执行此操作。

产生此结果的源代码的缩减列表如下所示。在示例代码中,ExecuteSomeSql()ExecuteSomeSqlDifferently()被标记为ExecuteSomeLocalSql()不存在的漏洞。

对于Analysis Evidence,它仅列出了OracleCommand的创建行: enter image description here

  

TestDao.cs:27 - OracleCommand()

     

RuleID:31D4607A-A3FF-447C-908A-CA2BBE4CE4B7

在其提供的问题的详细信息中:

  

在TestDao.cs的第27行,ExecuteSomeSql()方法调用SQL查询   使用来自不受信任来源的输入构建。这个电话可以   允许攻击者修改语句的含义或执行   任意SQL命令。

Fortify针对此问题提供的示例图表: ExecuteSomeSql Diagram

经过大量搜索,我发现这篇文章描述了一个类似的问题并提出了解决方案:Can I register a trusted source for SQL statements

按照其中的说明操作,并在different version of the user guide(第90页)中单独验证说明

结果没有变化。我添加了一个额外的SQL注入验证规则'规则,具体描述为" ...标识在SQL查询中使用它们之前正确验证数据的函数。"

仍然无济于事。

编辑: 我更多地使用了自定义规则,并且能够确定CustomCleanseRules实际上正在应用(它们确实删除了其他类型的污点),但是没有删除一些特定于信任的标志Fortify适用于我们的内部库。

我库中任何方法返回的每个值都是不可信的,我创建的所有规则似乎都无法消除这种不信任。

我做错了什么,或者Fortify不起作用?

是否需要采用不同类型的规则来消除这种普遍的不信任?

示例源代码:

在图书馆:

namespace Our.Utilities.Database
{
    public abstract class BaseDao
    {
        protected string ReadEmbeddedSql(string key)
        {
            //... extract sql from assembly
            return sql;
        }
    }
}

在申请中:

namespace Our.Application.DataAccess
{
    public class TestDao: Our.Utilities.Database.BaseDao
    {
        public void ExecuteSomeSql()
        {
            //... connection is created
            // Fortify Does not trust sqlText returned from library method.
            var sqlText = ReadEmbeddedSql("sql.for.ExecuteSomeSql");
            using(var someSqlCommand = new OracleCommand(sqlText, connection)) // Fortify flags creation of OracleCommand as SqlInjection vulnerability.
            {
                 someSqlCommand.ExecuteNonQuery();
            }
        }
        public void ExecuteSomeSqlDifferently()
        {
            //... connection is created
            // Fortify Does not trust sqlText returned from library method.
            var sqlText = ReadEmbeddedSql("sql.for.ExecuteSomeSql");
            using(var someSqlCommand = connection.CreateCommand()) 
            {
                 someSqlCommand.CommandText = sqlText; //Fortify flags setting CommandText as SqlInjection vulnerability.
                 someSqlCommand.ExecuteNonQuery();
            }
        }
        public void ExecuteSomeLocalSql()
        {

            //... connection is created
            var sqlText = ReadEmbeddedSqlLocallyDefined("sql.for.ExecuteSomeSql");
            using(var someSqlCommand = new OracleCommand(sqlText, connection))
            {
                 someSqlCommand.ExecuteNonQuery();
            }
        }
        protected string ReadEmbeddedSqlLocallyDefined(string key)
        {
            //... extract sql from assembly
            return sql;
        }
    }
}

自定义规则的XML:

<?xml version="1.0" encoding="UTF-8"?>
<RulePack xmlns="xmlns://www.fortifysoftware.com/schema/rules">
    <RulePackID>5A78FC44-4EEB-49C7-91DA-6564805C3F23</RulePackID>
    <SKU>SKU-C:\local\path\to\custom\rules\Our-Utilities</SKU>
    <Name><![CDATA[C:\local\path\to\custom\rules\Our-Utilities]]></Name>
    <Version>1.0</Version>
    <Description><![CDATA[]]></Description>
    <Rules version="17.10">
        <RuleDefinitions>
            <DataflowCleanseRule formatVersion="17.10" language="dotnet">
                <RuleID>7C49FEDA-AA67-490D-8820-684F3BDD58B7</RuleID>
                <FunctionIdentifier>
                    <NamespaceName>
                        <Pattern>Our.Utilities.Database</Pattern>
                    </NamespaceName>
                    <ClassName>
                        <Pattern>BaseDao</Pattern>
                    </ClassName>
                    <FunctionName>
                        <Pattern>ReadSqlTemplate</Pattern>
                    </FunctionName>
                    <ApplyTo implements="true" overrides="true" extends="true"/>
                </FunctionIdentifier>
                <OutArguments>return</OutArguments>
            </DataflowCleanseRule>
            <DataflowCleanseRule formatVersion="17.10" language="dotnet">
                <RuleID>14C423ED-5A51-4BA1-BAE1-075E566BE58D</RuleID>
                <TaintFlags>+VALIDATED_SQL_INJECTION</TaintFlags>
                <FunctionIdentifier>
                    <NamespaceName>
                        <Pattern>Our.Utilities.Database</Pattern>
                    </NamespaceName>
                    <ClassName>
                        <Pattern>BaseDao</Pattern>
                    </ClassName>
                    <FunctionName>
                        <Pattern>ReadSqlTemplate</Pattern>
                    </FunctionName>
                    <ApplyTo implements="true" overrides="true" extends="true"/>
                </FunctionIdentifier>
                <OutArguments>return</OutArguments>
            </DataflowCleanseRule>
        </RuleDefinitions>
    </Rules>
</RulePack>

1 个答案:

答案 0 :(得分:1)

当我运行你的示例代码时(我必须修改它,因为它不会按原样编译)。当我使用SCA 17.10和2017Q3运行时(我在2017Q2也这样做了)我没有得到与你相同的SQL注入规则ID。

查看您的分析证据,我假设发现这个的分析器不是数据流或控制流,但可能是语义或结构?

您可以通过查看摘要标签查看找到结果的分析器类型:

Displaying the summary tab of Visual Studio Fortify plugin, highlighting the analyzer engine that found the specific issue selected.

无论哪种方式,我都不认为我会在这里做自定义规则。

您可以执行的选项是使用过滤器文件。

这个文件可以包含

  • RuleIDs
  • InstanceIDs
  • 分类

当此文件传递给scan命令时,任何与过滤器文件中的任何字段匹配的查找都将从结果中过滤掉。

您可以在<SCA Install Dir>\Samples\Advanced\filter

中找到使用过滤器文件的示例

或者您可以查看附录B:过滤分析中的Fortify SCA Users Guide

*注意:您对使用过滤器的评论(在评论中)是现场的。