【问题标题】:How to safe interpolate strings in slick如何在 slick 中安全地插入字符串
【发布时间】:2020-01-31 22:16:40
【问题描述】:

我有一个可以有不同 where 子句的 sql 查询。我想将此子句动态插入到普通 sql 中:

val v1 = s"id = $id AND secondId IS NULL"
val v2 = s"secondId = $secondId"

val whereCondition = //v1 or v2 at runtime   

val query = sql"select id from users where #$whereCondition"

如您所见,在 sql 注入的情况下是不安全的。有更安全的方法来构建这个 sql 吗?

【问题讨论】:

  • 如果可以的话,我建议不要在这里使用plain-sql,而是动态构建查询
  • 我同意这一点。使用 slick 的类型安全查询而不是普通的 sql 查询。阅读:Slick type-safe, composable queries。这样 Slick 将处理 SQL 注入漏洞。

标签: scala slick slick-3.0


【解决方案1】:

你可以有一个 queryConcatenator trait,它基本上将 SQLAction 组合在一起以动态创建 sql。

trait QueryConcatenator {
      def concatQuery(firstQuery: SQLActionBuilder, secondQuery: SQLActionBuilder): SQLActionBuilder = {
        SQLActionBuilder(
          firstQuery.queryParts ++ secondQuery.queryParts,
          new SetParameter[Unit] {
            override def apply(v1: Unit, v2: PositionedParameters): Unit = {
              firstQuery.unitPConv.apply(v1, v2)
              secondQuery.unitPConv.apply(v1, v2)
            }
          }
        )
      }
    

然后你的 DbRepo 可以扩展连接器,你就在路上

    class DbRepo extends QueryConcatenator {
      def withDynamicFilter(maybeProductId:Option[Long]):Future[Vector[Product]] = {

      val baseStatement = Seq(sql"""select * from products""")
      val maybeFilter = if (maybeProductId.isEmpty) Seq(sql"") else Seq(sql" and productId = ${maybeProductId.get}")
      val concatenatedSql = baseStatement ++ maybeFilter
      val concatenatedActionBuilders =
        concatenatedSql.reduce((query1, query2) => concatQuery(query1, query2))

      db.run(concatenatedActionBuilders.as[Product])}
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 2011-05-08
    • 2010-09-22
    • 1970-01-01
    • 2011-12-28
    • 2012-09-13
    相关资源
    最近更新 更多