swift.sqllite.sqllite-injection-audit.swift-potential-sqlite-injection
semgrep
Author
unknown
Download Count*
License
Potential Client-side SQL injection which has different impacts depending on the SQL use-case. The impact may include the circumvention of local authentication mechanisms, obtaining of sensitive data from the app, or manipulation of client-side behavior. It wasn't possible to make certain that the source is untrusted, but the application should avoid concatenating dynamic data into SQL queries and should instead leverage parameterized queries.
Run Locally
Run in CI
Defintion
rules:
- id: swift-potential-sqlite-injection
message: Potential Client-side SQL injection which has different impacts
depending on the SQL use-case. The impact may include the circumvention of
local authentication mechanisms, obtaining of sensitive data from the app,
or manipulation of client-side behavior. It wasn't possible to make
certain that the source is untrusted, but the application should avoid
concatenating dynamic data into SQL queries and should instead leverage
parameterized queries.
severity: WARNING
metadata:
likelihood: MEDIUM
impact: MEDIUM
confidence: LOW
category: security
cwe:
- "CWE-89: Improper Neutralization of Special Elements used in an SQL
Command ('SQL Injection')"
masvs:
- "MASVS-CODE-4: The app validates and sanitizes all untrusted inputs."
references:
- https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html
subcategory:
- vuln
technology:
- ios
- macos
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- SQL Injection
languages:
- swift
mode: taint
pattern-sources:
- pattern-either:
- pattern: |
"...\($X)..."
- pattern: |
$SQL = "..." + $X
- pattern: |
$SQL = $X + "..."
pattern-sinks:
- patterns:
- pattern-either:
- pattern: sqlite3_exec($DB, $SQL, ...)
- pattern: sqlite3_prepare_v2($DB, $SQL, ...)
- focus-metavariable:
- $SQL
Examples
sqllite-injection-audit.swift
let username = someField.text()
let password = a.text()
let sql = "SELECT * FROM semgrep_users WHERE username = '\(username)' AND password = '\(password)'"
// ruleid:swift-potential-sqlite-injection
let result = sqlite3_exec(db, sql, nil, nil, nil)
sqlite3_close(db)
let sql = "SELECT * FROM semgrep_users WHERE username = 'admin' AND password = '\(password)'"
// ruleid:swift-potential-sqlite-injection
let result = sqlite3_exec(db, sql, nil, nil, nil)
sqlite3_close(db)
let sql = "SELECT * FROM semgrep_users WHERE username = ? AND password = ?"
var stmt: OpaquePointer?
// okid:swift-potential-sqlite-injection
if sqlite3_prepare_v2(db, sql, -1, &stmt, nil) == SQLITE_OK {
sqlite3_bind_text(stmt, 1, username, -1, nil)
sqlite3_bind_text(stmt, 2, password, -1, nil)
if sqlite3_step(stmt) == SQLITE_DONE {
// SUCCESS
}
}
sqlite3_finalize(stmt)
sqlite3_close(db)
let sql = "SELECT * FROM semgrep_users WHERE username = 'admin' AND password = 'admin'"
// okid:swift-potential-sqlite-injection
let result = sqlite3_exec(db, sql, nil, nil, nil)
sqlite3_close(db)
let theUsername = "admin"
let sql = "SELECT * FROM semgrep_users WHERE username = '" + theUsername + "' AND password = 'admin'"
// FP but cant do much about this I dont think
// ruleid:swift-potential-sqlite-injection
let result = sqlite3_exec(db, sql, nil, nil, nil)
sqlite3_close(db)
let newUser = getUsernameFromServer()
let sql = "SELECT * FROM semgrep_users WHERE username = '" + newUser + "' AND password = 'admin'"
// ruleid:swift-potential-sqlite-injection
let result = sqlite3_exec(db, sql, nil, nil, nil)
sqlite3_close(db)
let sql = "SELECT * FROM semgrep_users WHERE username = 'admin' AND password = '" + password + "'"
// ruleid:swift-potential-sqlite-injection
let result = sqlite3_exec(db, sql, nil, nil, nil)
sqlite3_close(db)
let sql = "SELECT * FROM semgrep_users WHERE username = ? AND password = '" + password + "'"
// ruleid:swift-potential-sqlite-injection
if sqlite3_prepare_v2(db, sql, -1, &stmt, nil) == SQLITE_OK {
sqlite3_bind_text(stmt, 1, username, -1, nil)
if sqlite3_step(stmt) == SQLITE_DONE {
// SUCCESS
}
}
sqlite3_finalize(stmt)
sqlite3_close(db)
Short Link: https://sg.run/lkwo