説明
ユーザー入力から組み立てたSQLを実行すると、攻撃者にクエリの構造を変更され、認証の回避やデータの取得、変更、削除につながるおそれがあります。
想定される影響
- 認証や権限チェックの回避
- 機密データの取得や改ざん
- データの削除やサービスの停止
対処方法
- SQL文字列にユーザー入力を連結したり、文字列補間で埋め込んだりしないでください。
- SQLiteのバインディング、プリペアドステートメント、ORMのクエリビルダーなど、クエリの構造と値を分離するAPIを使います。
- テーブル名や列名など、値としてバインドできない識別子は許可リストから選びます。
例
変更前
swift
let query = "SELECT * FROM users WHERE name = '\(username)'"
try db.execute(query)
変更後
swift
import GRDB
func findUser(db: Database, username: String) throws -> Row? {
return try Row.fetchOne(
db,
sql: "SELECT * FROM users WHERE name = ?",
arguments: [username])
}
説明:
- 変更前: ユーザー入力がSQLの構造に直接組み込まれます。
- 変更後: GRDBの
Row.fetchOneにバインド引数を渡して結果を取得します。クエリの構造と値を分離するため、入力をデータとして扱えます。