Der sql
Präfix entriegelt ein StringContext
, wo Sie SQL-Parameter einstellen können. Es gibt keinen SQL-Parameter für eine Liste, so dass Sie sich hier leicht öffnen können, wenn Sie nicht vorsichtig sind. Es gibt einige gute (und einige gefährliche) Vorschläge zum Umgang mit diesem Problem mit SQLServer unter this question. Sie haben ein paar Optionen:
Ihre beste Wette ist wahrscheinlich den #$
Operator verwenden zusammen mit mkString
dynamischen SQL zu interpolieren:
val sql = sql"""SELECT * FROM coffee WHERE id IN (#${ids.mkString(",")})"""
Dies gilt nicht richtig Parameter verwenden, und daher könnte sein, offen für SQL- Injektion und andere Probleme.
Eine weitere Option ist die regelmäßige String-Interpolation zu verwenden und mkString
die Aussage zu bauen:
val query = s"""SELECT * FROM coffee WHERE id IN (${ids.mkString(",")})"""
StaticQuery.queryNA[Coffee](query)
Dies ist im Wesentlichen der gleiche Ansatz wie #$
verwenden, aber möglicherweise flexibler im allgemeinen Fall.
Wenn die Sicherheitsanfälligkeit durch SQL-Injection von großer Bedeutung ist (z. B. wenn die Elemente von ids
vom Benutzer bereitgestellt werden), können Sie eine Abfrage mit einem Parameter für jedes Element von ids
erstellen. Dann müssen Sie eine benutzerdefinierte SetParameter
Instanz schaffen, so dass glatte die List
in Parameter drehen kann:
implicit val setStringListParameter = new SetParameter[List[String]]{
def apply(v1: List[String], v2: PositionedParameters): Unit = {
v1.foreach(v2.setString)
}
}
val idsInClause = List.fill(ids.length)("?").mkString("(", ",", ")")
val query = s"""SELECT * FROM coffee WHERE id IN ($idsInClause)"""
Q.query[List[String], String](query).apply(ids).list(s)
Da Ihr ids
Ints
sind, ist dies wahrscheinlich weniger ein Problem, aber wenn Sie diese Methode bevorzugen, Sie müssten nur die setStringListParameter
ändern Int
statt String
zu verwenden:
Wenn 'ids' Typ 'List [Int]' 'Ich kann nicht sehen, wie SQL-Injektion möglich ist, auch wenn sie Benutzer zur Verfügung gestellt werden. – Daenyth
@Daenyth Es ist definitiv weniger Besorgnis (obwohl manchmal ganzzahlige SQL-Injection ein Problem sein kann, durch eine Division durch Null oder andere Ausnahmen verursachen, und dann den gescheiterten Zustand ausnutzen - Google "sql injection Ganzzahlen"). Aber ich würde sagen, dass es am besten ist, Parameter zu verwenden, um Probleme auf der Straße zu vermeiden (z. B. wenn ein anderer Entwickler den Typ in "String" geändert hat, um die neuen Typen von IDs aufzunehmen, die einige Zeichen enthalten). Ich habe wirklich nur über den Fall gesprochen, als es hier eine "Schnur" ist. –
Danke für die Antwort Ben! Sehr informativ über die Lösungen mit möglichen Schwachstellen. Ich stimme jedoch @ Daenyth zu, dass Sie nicht mit einem expliziten Ganzzahl-Typ injizieren können. –