代码之家  ›  专栏  ›  技术社区  ›  Markos Fragkakis

阻止从窗体生成的SQL注入SQL-无PreparedStmts

  •  4
  • Markos Fragkakis  · 技术社区  · 16 年前

    我有一个搜索表,用户可以在其中使用以下类型的筛选器筛选结果:

    • 字段[名称],值[约翰], 规则
    • 字段[姓氏],值[布莱克],
    • 删除规则
    • 添加规则

    因此,用户将能够设置任意一组过滤器,这将从本质上产生一个完全动态的WHERE子句。在将来,我还要实现更复杂的逻辑表达式,比如

    其中(姓名=约翰或姓名=尼克)和(姓氏=布莱克或姓氏=伯恩),

    在所有10个用户可以或不可以过滤的字段中,我不知道用户将设置多少和哪些过滤器。因此,我不能使用prepared语句(假设至少我们知道WHERE子句中的字段)。这就是为什么准备好的语句很不幸是不可能的,我必须用普通的、旧的、生成的SQL来完成它。

    3 回复  |  直到 16 年前
        1
  •  5
  •   Will Hartung    16 年前

    Java,未经测试。

    List<String> clauses = new ArrayList<String>();
    List<String> binds = new ArrayList<String>();
    
    if (request.name != null) {
        binds.add(request.name);
        clauses.add("NAME = ?");
    }
    
    if (request.city != null) {
        binds.add(request.city);
        clauses.add("CITY = ?");
    }
    
    ...
    
    String whereClause = "";
    
    for(String clause : clauses) {
        if (whereClause.length() > 0) {
            whereClause = whereClause + " AND ";
        }
        whereClause = whereClause + clause;
    }
    
    String sql = "SELECT * FROM table WHERE " + whereClause;
    
    PreparedStatement ps = con.prepareStatment(sql);
    
    int col = 1;
    for(String bind : binds) {
        ps.setString(col++, bind);
    }
    
    ResultSet rs = ps.executeQuery();
    
        2
  •  2
  •   Oskar Kjellin    16 年前

    conn = pool.getConnection( );
    String selectStatement = "SELECT * FROM User WHERE userId = ? ";
    PreparedStatement prepStmt = con.prepareStatement(selectStatement);
    prepStmt.setString(1, userId);
    ResultSet rs = prepStmt.executeQuery();
    
        3
  •  2
  •   Community Mohan Dere    9 年前

    SQL Server: Dynamic where-clause

    动态地构建where子句,但是使用参数名。