설명
사용자 입력을 결합해 만든 문자열을 SQL 쿼리로 실행하면 공격자가 쿼리 구조를 바꾸어 인증 우회, 데이터 조회, 수정, 삭제를 유발할 수 있습니다.
잠재적 영향
- 인증 또는 권한 검사 우회
- 민감 데이터 조회와 변조
- 데이터 삭제 또는 서비스 중단
해결 방법
- SQL 문자열에 사용자 입력을 결합하거나 보간하지 않습니다.
- SQLite 바인딩, prepared statement, ORM query builder처럼 쿼리 구조와 값을 분리하는 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과 바인딩 인자 API로 조회 결과를 읽으면서 SQL 구조와 값을 분리해 입력이 데이터로만 처리되게 합니다.