这是允许用户进行通配符搜索的正确方法吗?

时间:2011-10-14 06:17:20

标签: java sql security wildcard parameterized-query

例如,给定一个文本框名称,用户要求希望能够进行通配符搜索(例如contains,starts with,ends with)。

只要我仍在后端(Java)中使用参数化查询,是否可以接受sql通配符('%'和'_')作为输入?实际上,允许用户构建自己的正则表达式,这是用户的要求所在。

示例:

  1. 中的用户类型
    textbox = '%are%'
    
  2. 此参数以后端方式提供给后端:

    public class PersonDaoImpl {
    
            public List<Person> search(String name){//name gets the value from textbox w/ sql wildcards
            Query q = mgr.createNativeQuery('select * from Person where name like :name'); //default to always use like since expecting searchkey with sql wildcards    
            q.setParameter('name', name);//gives the input from the screen
            return q.getResultList();
            } 
    }  
    
  3. 结果集将包括名称为“Waren”,“Jared”,“Clare”,“Blare”的人,因为用户提供了正则表达式。
  4. 使用SQL Parameterize Query,我可以确保不会允许SQL注入。这实现了用户对通配符搜索的要求,但是它可能违反了我可能错过的任何内容吗?

    更新: 刚刚发现Google也允许通配符来自help page

3 个答案:

答案 0 :(得分:3)

嗯,这违反了用户需要知道(或被告知)如何构造SQL“LIKE”语法的事实,但这就是全部。你可能会以这种方式得到一个慢查询,因为它通常不能使用索引,但我不会担心安全性或正确性。

答案 1 :(得分:2)

这是“安全的”,但可能不是一个好主意,原因有两个:

  1. 要求您的用户知道sql语法可能不是最好的ui设计。
  2. 性能可怕:这些查询通常无法使用您的索引,因此执行起来很慢。并且它们需要大量的CPU时间来比较所有文本,因此它们会给您的服务器增加很多负载(与已经很高的执行时间不成比例)。您需要一种依赖于全文索引的解决方案。

答案 2 :(得分:0)

我很好奇,name参数如何在请求中设置?这是什么平台?(OP早先错过了setParameter

正如您所指出的,用户需要知道通配符语法,即使用%_等。更流行的方法是从用户名获取字符串,以及“完全匹配”选项/“以'/'名字命名'开头”。如果你走这条路线,你也可以在前两种情况下执行更有效的查询。

编辑:

如果客户坚持contains查询,那么我认为您当前的方法是要求最终用户更好地输入模式,然后通过在其周围放置%将输入字符串转换为模式。

这是因为用户仍然可以选择%添加(或有选择地添加)到搜索字符串,从而加快查询执行速度。例如:

  • 如果用户输入搜索字符串Don,则查询为select ... from ... where name like 'Don'。 RDBMS很可能会使用名称上的索引。

  • 如果用户输入搜索字符串Don%,则查询为select ... from ... where name like 'Don%'。 RDBMS仍然很可能在名称上使用索引。

  • 如果用户输入搜索字符串%Don%Don%,则无法使用索引。