代码之家  ›  专栏  ›  技术社区  ›  John Henckel

如何生成不易受SQL注入攻击的字符串

  •  4
  • John Henckel  · 技术社区  · 6 年前

    .

    这是我的C代码

        public static string[] GenerateQueries(string TableName, string ColumnName)
        {
            return new string[] {
                "SELECT * FROM " + TableName,
                "SELECT * FROM " + TableName + " WHERE 1=2",
                "SELECT * FROM " + TableName + " WHERE [" + TableName + "Id] = @id",
                "SELECT * FROM " + TableName + " WHERE [" + TableName + "Id] = IDENT_CURRENT('" + TableName + "')",
                "SELECT * FROM " + TableName + " WHERE [" + ColumnName + "] = @value"
            };
        }
    

    叫它吧 只有 使用常量字符串,例如

    var queryList = GenerateQueries("Person", "Name");
    

    有没有办法重写这个函数使它“安全”呢?例如,如果我使用C而不是C#,我可以编写一个

    目前,我唯一的选择就是 复制/粘贴 ,这是丑陋和维护负担。

    复制/粘贴真的是我唯一的选择吗?

    谢谢你的回复,特别是威廉·莱德。现在我发现我的问题是错误的。这不仅仅是因为我连接了查询字符串,而且还将它们存储在 变量 构建 SqlDataAdapter 使用常量 比如,

    var adapter = new SqlDataAdapter("SELECT * FROM PERSON");
    

    2 回复  |  直到 6 年前
        1
  •  2
  •   Community CDub    5 年前

    一开始我很震惊,但经过思考,这和代码中已经有一个SQL语句没有什么不同,它看起来像这样:

    "SELECT * FROM Person"
    

    我们总是做那种事。

    这里有一个重要的警告。这只是事实 某个数据层类的成员 可以 没事吧。但我也想知道这到底有多有用。似乎你没有从编写查询中节省太多。

    另外,养成忽略静态分析工具的习惯是不好的。有时他们给你的东西你只是知道是错误的,但你改变它无论如何,以便当他们 找到一些重要的东西,你不习惯忽略它。

        2
  •  0
  •   Bill Richards    6 年前

    如果您是通过您打开的连接发送原始SQL,那么是否使用宏来生成SQL语句一点都不重要

    将SQL命令发送到进行未批准调用的端点。如果我们启动一个网络包嗅探器,我们可以看到您有一个数据库配置为允许发送SQL命令,因此我们可以将非法SQL注入到系统中

    您仍然可以依赖单个过程来调用更新,但是如果您选择转到过程,为什么要这样做?

    编辑 举个例子

    create PROC sp_CommonSelectFromTableProc @tableName varchar(32)
    AS
       -- code to check the tableName parameter does not contain SQL and/or is a valid tableName
    
       -- your procedure code here will probable use 
       --  exec mydynamicSQLString  
       -- where mydynamicSQLString is constructed using @tableName  
    END;
    

    create PROC sp_SelectFromSpecificTableProc 
    AS
       SELECT * FROM SpecificTable
    END;
    

    重要的是要记住 SQL注入是 独立于技术 .

    当应用程序包含如下构造时,它是公开的

    return new string[] {
                "SELECT * FROM " + TableName,
                "SELECT * FROM " + TableName + " WHERE 1=2",
                "SELECT * FROM " + TableName + " WHERE [" + TableName + "Id] = @id",
                "SELECT * FROM " + TableName + " WHERE [" + TableName + "Id] = IDENT_CURRENT('" + TableName + "')",
                "SELECT * FROM " + TableName + " WHERE [" + ColumnName + "] = @value"
    

    Here 对于理解如何减轻SQL注入攻击来说,这是一个非常好的起点