首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在动态生成DDL时防止SQL注入?

如何在动态生成DDL时防止SQL注入?
EN

Stack Overflow用户
提问于 2019-01-01 03:32:52
回答 1查看 1K关注 0票数 2

目标:动态生成对SQL注入的PreparedStatement免疫。

代码语言:javascript
复制
    // This is a bad method. SQL injection danger . But it works 
    private PreparedStatement generateSQLBad(Connection connection, String tableName, 
        String columnName, String columnType) throws SQLException {
        String sql = "create table " + tableName + " (" + columnName + " " + columnType + ")";
        PreparedStatement create = connection.prepareStatement(sql);
        return create;
    }

    // I tried this. But it didn't work  
    private PreparedStatement generateSQLGood(Connection connection, String tableName, 
        String columnName, String columnType) throws SQLException {
        String sql = "create table ? (? ?)";
        PreparedStatement create = connection.prepareStatement(sql);
        create.setString(1, tableName);
        create.setString(2, columnName);
        create.setString(3, columnType);
        return create;
    } 

如何动态生成PreparedStatement,用户可以选择表名、列类型等而不存在注入的危险?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-01 19:40:46

不能将?参数占位符用于标识符(表名和列名)。它们也不能用于SQL关键字,比如数据类型。准备查询需要能够验证语法,并验证您的表名等等是否合法。这必须在准备时间完成,而不是在执行时间。SQL不允许参数包含语法。它们总是被视为标量值。这就是它们如何防止SQL注入的方式。

因此,参数只能用于替换标量文本,例如引号字符串或日期,或数字值。

如何处理动态标识符?如注释所示,最好的方法是过滤输入,这样它们就不会引入SQL注入。在某种程度上,部分基于用户输入的动态SQL是 SQL注入。你只需要以一种控制的方式允许它。

如果分隔标识符,所有SQL实现都允许在表名中使用特殊字符。标准SQL对分隔符使用双引号.MySQL使用倒计时,使用方括号。

关键是,您可以用这种方式制作奇怪的表名,比如包含空格、标点符号、国际字符或SQL保留词的表名。

代码语言:javascript
复制
CREATE TABLE "my table" ( col1 VARCHAR(20) );

CREATE TABLE "order" ( col1 VARCHAR(20) );

也见我对https://stackoverflow.com/a/214344/20860的回答

但是,如果表名本身包含文字双引号呢?那你必须逃离那个角色。要么使用双字符,要么使用反斜杠:

代码语言:javascript
复制
CREATE TABLE "Dwayne ""The Rock"" Johnson" ( col1 VARCHAR(20) );

CREATE TABLE "Dwayne \"The Rock\" Johnson" ( col1 VARCHAR(20) );

您也可以设计函数来检查这些字符的动态表名,或者删除它们,或者抛出异常。

但是,即使通过仔细过滤输入使语句安全,这也不可能满足checkmarx警告。SQL注入测试人员无法分析您的自定义代码,以确保它可靠地过滤输入。

您可能只需尽最大努力使动态SQL安全,因为您知道checkmarx总是会抱怨它。在代码中编写注释,向阅读代码的未来开发人员解释您的安全措施。

还编写单元测试,以确保危险的输入导致安全的DDL语句或其他异常。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53992860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档