C.W.K.
Stream
Lesson 03 of 10 · published

Parameterized Query — SQL Injection 멈춰

~14 min · python, parameters, sql-injection, security

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

가장 중요한 single rule

유저 input 으로 string concat / f-string 으로 SQL 절대 빌드 X. Placeholder 쓰고 parameter 따로. 드라이버가 escaping 처리; SQL injection 이 구조적으로 불가능.

SQLite 가 placeholder 스타일 2 가지:

  • Qmark: ? + tuple/list. 순서 기반.
  • Named: :name + dict. Self-documenting.
Warning: conn.execute(f'SELECT * FROM users WHERE name = "{name}"') 는 보안 버그. 같은 패턴이 production 에서 무수한 데이터 유출 root cause. Placeholder 항상 — 'trusted' input 도. Trusted 는 미끄러운 속성.

Placeholder 가 못 하는 거 = identifier (테이블명, 컬럼명) parameterize. 그건 allowlist 검증 후에만 SQL string 에 format.

Code

Placeholder 두 스타일, 둘 다 안전·python
# Qmark — 순서 기반
conn.execute(
    'SELECT * FROM users WHERE email = ? AND archived = ?',
    ('a@x.com', 0),
)

# Named — dict 기반, self-documenting
conn.execute(
    'SELECT * FROM users WHERE email = :email AND archived = :archived',
    {'email': 'a@x.com', 'archived': 0},
)

# 다중 row — 같은 placeholder, executemany
conn.executemany(
    'INSERT INTO users(email, username) VALUES (?, ?)',
    [('a@x.com', 'alice'), ('b@x.com', 'bob')],
)
Identifier — allowlist 검증·python
ALLOWED_SORT = {'created_at', 'updated_at', 'id'}

def list_messages(conn, sort_by: str):
    if sort_by not in ALLOWED_SORT:
        raise ValueError(f'invalid sort: {sort_by}')
    # 이제 알려진 상수 값이라 format 안전
    return conn.execute(
        f'SELECT * FROM messages ORDER BY {sort_by} DESC LIMIT 100'
    ).fetchall()
SQL injection 시도 — placeholder 가 어떻게 죽이나·python
# UNSAFE — 절대 X
name = "alice'; DROP TABLE users; --"
conn.execute(f"SELECT * FROM users WHERE name = '{name}'")
# users 안녕.

# SAFE — placeholder 가 string 전체를 값으로 처리
conn.execute('SELECT * FROM users WHERE name = ?', (name,))
# 그냥 row 0 반환; 테이블 무사.

External links

Exercise

작은 vulnerable 함수 (string-concat SQL) + 테이블 drop 또는 query escalation 하는 exploit input. 그 다음 placeholder 로 재작성, 같은 input 이 무해함 확인. Diff 문서화. 보너스: 본인 codebase 에서 f-string SQL 검색 — 적어도 하나 찾을 거.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.