Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions swift/ql/src/queries/Security/CWE-089/SqlInjection.qhelp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ If a database query (such as a SQL query) is built from user-provided data witho
<recommendation>

<p>
Most database connector libraries offer a way to safely embed untrusted data into a query using query parameters or prepared statements. You should use these features to build queries, rather than string concatenation or similar methods without sufficient sanitization.
Most database connector libraries offer a way to safely embed untrusted data into a query using query parameters or prepared statements. You should use these features to build queries, rather than string concatenation or similar methods. You can also escape (sanitize) user-controlled strings so that they can be included directly in an SQL command. A library function should be used for escaping, because this approach is only safe if the escaping function is robust against all possible inputs.
</p>

</recommendation>
<example>

<p>In the following example, a SQL query is prepared using string interpolation to directly include a user-controlled value <code>userControlledString</code> in the query. An attacker could craft <code>userControlledString</code> to change the overall meaning of the SQL query.
<p>In the following examples, an SQL query is prepared using string interpolation to directly include a user-controlled value <code>userControlledString</code> in the query. An attacker could craft <code>userControlledString</code> to change the overall meaning of the SQL query.
</p>

<sample src="SqlInjectionBad.swift" />
Expand All @@ -35,4 +35,4 @@ Most database connector libraries offer a way to safely embed untrusted data int
<li>OWASP: <a href="https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html">SQL Injection Prevention Cheat Sheet</a>.</li>

</references>
</qhelp>
</qhelp>
13 changes: 11 additions & 2 deletions swift/ql/src/queries/Security/CWE-089/SqlInjectionBad.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
let unsafeQuery = "SELECT * FROM users WHERE username='\(userControlledString)'" // BAD
// with SQLite.swift

try db.execute(unsafeQuery)
let unsafeQuery = "SELECT * FROM users WHERE username='\(userControlledString)'"

try db.execute(unsafeQuery) // BAD

let stmt = try db.prepare(unsafeQuery) // also BAD
try stmt.run()

// with SQLite3 C API

let result = sqlite3_exec(db, unsafeQuery, nil, nil, nil) // BAD
17 changes: 16 additions & 1 deletion swift/ql/src/queries/Security/CWE-089/SqlInjectionGood.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
// with SQLite.swift

let safeQuery = "SELECT * FROM users WHERE username=?"

let stmt = try db.prepare(safeQuery, userControlledString) // GOOD
try stmt2.run()
try stmt.run()

// with sqlite3 C API

var stmt2: OpaquePointer?

if (sqlite3_prepare_v2(db, safeQuery, -1, &stmt2, nil) == SQLITE_OK) {
if (sqlite3_bind_text(stmt2, 1, userControlledString, -1, SQLITE_TRANSIENT) == SQLITE_OK) { // GOOD
let result = sqlite3_step(stmt2)

// ...
}
sqlite3_finalize(stmt2)
}