SQL Injection

์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋ณด์•ˆ์ƒ์˜ ํ—ˆ์ ์„ ์•…์šฉํ•ด ์ž„์˜์˜ SQL๋ฌธ์„ ์‹คํ–‰์‹œํ‚ค๋Š” ์ธ์ ์…˜ ๊ณต๊ฒฉ ๊ธฐ๋ฒ•

์ธ์ ์…˜ ๊ณต๊ฒฉ

์ •์ƒ์ ์ด์ง€ ์•Š์€ ์ž…๋ ฅ๊ฐ’์„ ํ”„๋กœ๊ทธ๋žจ์— ์ฃผ์ž…ํ•˜์—ฌ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์ด๋‹ค. ์ธ์ ์…˜ ๊ณต๊ฒฉ์€ ํ”„๋กœ๊ทธ๋žจ์˜ ์ •์ƒ์ ์ธ ์‹คํ–‰์„ ๋ฐฉํ•ดํ•œ๋‹ค.

์ธ์ ์…˜ ๊ณต๊ฒฉ์€ ๊ณ ์ „์ ์ธ ๊ณต๊ฒฉ ๋ฐฉ๋ฒ•์ค‘ ํ•˜๋‚˜๋กœ ์ด ๊ณต๊ฒฉ์œผ๋กœ ์‹œ์Šคํ…œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋นผ๋‚ด๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๊ณ  Integrity ์ €ํ•˜, DOS ๊นŒ์ง€ ๊ฐ€๋Šฅํ•˜๋‹ค.

  • Code Injection

  • XSS (Cross-site Scripting)

  • SQL Injection

  • โ€ฆ

SQL ์ธ์ ์…˜

์•ž์—์„œ ๋งํ•œ๋ฐ”์™€ ๊ฐ™์ด SQL ์ธ์ ์…˜์€ ์•…์˜์ ์ธ SQL ๋ฌธ์„ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ธ์ ์…˜ ๊ณต๊ฒฉ์˜ ํ•œ ์ข…๋ฅ˜์ด๋‹ค. ์ด ๊ณต๊ฒฉ๋ฐฉ์‹์„ ํ†ตํ•ด ํ•ด์ปค๋Š” ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„ ๋„ˆ๋จธ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„๋ฅผ ์กฐ์ข…๋‹ค. ์ทจ์•ฝ์ ์„ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ธ์ฆ ๋“ฑ์˜ ๋ณด์•ˆ ์„ค์ •์„ ์šฐํšŒํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— CRUD ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

In-band SQL ์ธ์ ์…˜

๊ณ ์ „์ ์ธ SQL ์ธ์ ์…˜ ๊ณต๊ฒฉ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ณต๊ฒฉ์ž๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ™์€ ์ฑ„๋„์—์„œ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฒฉ ๋ฐฉ์‹์ด๋‹ค. ๊ณต๊ฒฉ์ž๊ฐ€ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ๊ณต๊ฒฉํ•˜๋ฉด ๊ฒฐ๊ณผ ๋˜ํ•œ ์›น ๋ธŒ๋ผ์šฐ์ €์— ์ถœ๋ ฅ๋œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๊ฐ€ ์‚ฌ์šฉ์ž์˜ ์ธํ’‹์„ ๋ฐ›์•„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฟผ๋ฆฌ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ณด๋‚ด๊ณ  ๊ฒฐ๊ณผ๋ฅผ ํ™”๋ฉด์— ๋ฟŒ๋ ค์ค€๋‹ค๊ณ  ํ•ด๋ณด์ž.

SELECT * FROM users WHERE user_id LIKE 'current_user'

๋งŒ์•ฝ ํ•ด์ปค๊ฐ€ current_user ์ž๋ฆฌ์— %'โ€” ๋ฅผ ์ง‘์–ด๋„ฃ๊ณ  ์„œ๋ฒ„์— ์š”์ฒญํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

SELECT * FROM users WHERE user_id LIKE '%'--'

mysql์—์„œ โ€˜โ€”โ€™ (๋”๋ธ” ๋Œ€์‰ฌ) ๋Š” ์ฃผ์„์ด๊ณ  โ€˜%โ€™ ๋Š” ์™€์ผ๋“œ์นด๋“œ๋ฅผ ์˜๋ฏธํ•˜๋ฏ€๋กœ ์ „์ฒด ์œ ์ €์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

Error-based SQL ์ธ์ ์…˜

In-band SQL ์ธ์ ์…˜ ๊ธฐ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ ์ผ๋ถ€๋Ÿฌ SQL ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์ด๋‹ค.

SELECT * FROM users WHERE user_id = 'current_user'

๋งŒ์•ฝ ํ•ด์ปค๊ฐ€ 1โ€™ ์„ ์ง‘์–ด๋„ฃ๊ณ  ์š”์ฒญํ•œ๋‹ค๋ฉด ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ณด๋‚ด์ง€๋Š” SQL์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์ด๋‹ค.

SELECT * FROM users WHERE user_id = '1''

๋’ค์— ๋”ฐ์˜ดํ‘œ๊ฐ€ ํ•˜๋‚˜ ๋” ๋ถ™์–ด์„œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ํ™”๋ฉด์— ๋ณด์—ฌ์ง„๋‹ค. ์ด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์—๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์–ด๋–ค ์ข…๋ฅ˜์ธ์ง€ (MySQL์ธ์ง€ Oracle์ธ์ง€) ๋“ฑ์˜ ์ •๋ณด๊ฐ€ ๋…ธ์ถœ๋˜์–ด ์žˆ๋‹ค. ํ•ด์ปค๋Š” ์ด ์ •๋ณด๋ฅผ ์ด์šฉํ•ด ๋” ๊ตฌ์ฒด์ ์ธ ๋‹ค๋ฅธ ๊ณต๊ฒฉ ๋ฐฉ์‹์„ ์‹œ๋„ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Union-based SQL ์ธ์ ์…˜

In-band SQL ์ธ์ ์…˜ ๊ธฐ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ ๊ธฐ์กด ์ฟผ๋ฆฌ์— union ๋ช…๋ น์–ด๋ฅผ ๋”ํ•ด ์•…์„ฑ ์ฟผ๋ฆฌ์™€์˜ ํ•ฉ์ง‘ํ•ฉ์„ ์ถœ๋ ฅํ•˜์—ฌ ์ •๋ณด๋ฅผ ํš๋“ํ•˜๋Š” ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์ด๋‹ค.

SELECT * FROM users WHERE user_id = 'current_user'

๋งŒ์•ฝ ํ•ด์ปค๊ฐ€ 1' UNION SELECT version(),current_user()--โ€™ ์„ ์ž…๋ ฅํ•œ๋‹ค๋ฉด ์‹ค์ œ๋กœ ๋ณด๋‚ด์ง€๋Š” SQL์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

SELECT * FROM users WHERE user_id = '-1' UNION SELECT version(),current_user()--'

์œ„ ์ฟผ๋ฆฌ์˜ ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ๋Š” ํ˜„์žฌ MySQL์˜ ๋ฒ„์ „๊ณผ ๋กœ๊ทธ์ธํ•œ ๊ณ„์ • ์ •๋ณด๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค. ๋‹จ union ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ธฐ์กด ์ฟผ๋ฆฌ์˜ ์ปฌ๋Ÿผ ์ˆ˜์™€ ์ถ”๊ฐ€ํ•œ ์ฟผ๋ฆฌ์˜ ์ปฌ๋Ÿผ ์ˆ˜๊ฐ€ ์ผ์น˜ํ•ด์•ผ ํ•œ๋‹ค.

Blind SQL ์ธ์ ์…˜

In-band SQLi ๋ฐฉ์‹๊ณผ ๋‹ฌ๋ฆฌ ๊ณต๊ฒฉ์„ ๊ฐ€ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ๋ถ€ํ„ฐ ์ •๋ณด๋ฅผ ํƒˆ์ทจํ•˜๋Š” ๋Œ€์‹  SQL ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„์™€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋™์ž‘์„ ๊ด€์ฐฐํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. In-based SQLi์— ๋น„ํ•ด ์‹œ๊ฐ„์€ ์ข€ ๋” ๊ฑธ๋ฆฌ์ง€๋งŒ ๋น„์Šทํ•œ ํšจ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋‹ค๋ฅธ ์ •๋ณด๋ฅผ ์–ป๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ณ  ๋‹ค๋ฅธ SQL ์ธ์ ์…˜ ๊ธฐ๋ฒ•์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์„์ง€ ์—ฌ๋ถ€๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

Boolean-based SQL ์ธ์ ์…˜

Blind SQL ์ธ์ ์…˜ ๊ธฐ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ boolean ์—ฐ์‚ฐ์ž๋ฅผ ์ฃผ์ž…์‹œํ‚ค๋Š” ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์ด๋‹ค. ์ฃผ์ž… ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์ฐธ/๊ฑฐ์ง“ ํŒจํ„ด์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋‹ค.

SELECT * FROM users WHERE user_id = 'current_user'

์˜ˆ๋ฅผ ๋“ค์–ด ์œ„ ์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์›น ์„œ๋ฒ„๊ฐ€ ์ฐธ/๊ฑฐ์ง“์„ ๋ฆฌํ„ดํ•ด์ค€๋‹ค๊ณ  ํ•ด๋ณด์ž.

SELECT * FROM users WHERE user_id = '12' AND 1=1
SELECT * FROM users WHERE user_id = '12' AND 1=0

์œ„ ์ฟผ๋ฆฌ์˜ 1=1 ๋ถ€๋ถ„๊ณผ 1=0 ๋ถ€๋ถ„์˜ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ์„œ ์ „์ฒด ์ฟผ๋ฆฌ์˜ ์ฐธ/๊ฑฐ์ง“ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ”๋€๋‹ค. ์ด ๋ถ€๋ถ„์— ์›ํ•˜๋Š” ์„œ๋ธŒ ์ฟผ๋ฆฌ๋ฅผ ๋„ฃ์œผ๋ฉด ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ์ฐธ์ธ์ง€ ๊ฑฐ์ง“์ธ์ง€๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ •๋ณด๋ฅผ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋‹ค.

SELECT * FROM users WHERE user_id = '12' AND (SELECT TOP 1 substring(name, 1, 1)
  FROM sysobjects
  WHERE id=(SELECT TOP 1 id
    FROM (SELECT TOP 1 id
      FROM sysobjects
      ORDER BY id)
    AS subq
    ORDER BY id DESC)) = 'a'

์ด ์„œ๋ธŒ์ฟผ๋ฆฌ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ฒซ ๋ฒˆ์งธ ํ…Œ์ด๋ธ”์ด a๋กœ ์‹œ์ž‘ํ•˜๋Š”์ง€๋ฅผ ํƒ์ƒ‰ํ•œ๋‹ค. ๋งŒ์•ฝ ์œ„ ์„œ๋ธŒ์ฟผ๋ฆฌ๊ฐ€ ์ฐธ์ด๋ผ๋ฉด AND 1=1 ๊ณผ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค. ์ด ์ž‘์—…์„ ์ˆ˜๋™์œผ๋กœ ํ•˜์ง€ ์•Š๊ณ  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์งœ์„œ ๊ฒ€์ƒ‰ํ•œ๋‹ค๋ฉด ์•„์ฃผ ์‰ฝ๊ฒŒ ๋ชจ๋“  ํ…Œ์ด๋ธ” ์ด๋ฆ„ ์ž๋ฆฟ์ˆ˜์— ๋Œ€ํ•˜์—ฌ ๋ชจ๋“  ์•ŒํŒŒ๋ฒณ์— ๋Œ€ํ•ด ๋ธŒ๋ฃจํŠธ ํฌ์Šค ๊ณต๊ฒฉ์„ ๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

Time-based SQL ์ธ์ ์…˜

Blind SQL ์ธ์ ์…˜ ๊ธฐ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ ์‹œ๊ฐ„ ๋”œ๋ ˆ์ด๋ฅผ ์ผ์œผํ‚ค๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ฃผ์ž…์‹œ์ผœ ๋ฐ์ดํ„ฐ๋ฅผ ํƒˆ์ทจํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด

SELECT * FROM users WHERE user_id = 'current_user'

์œ„ ์ฟผ๋ฆฌ์— ์‚ฌ์šฉ์ž๊ฐ€ 12; WAITFOR DELAY '0:0:10โ€™ ๋ฅผ ์ฃผ์ž…ํ–ˆ๋‹ค๊ณ  ํ•ด๋ณด์ž. ๊ทธ๋Ÿฌ๋ฉด ์ „์ฒด ์ฟผ๋ฆฌ๋Š”

SELECT * FROM users WHERE user_id = 12; WAITFOR DELAY '0:0:5'

์ด ์ฟผ๋ฆฌ๋Š” 5์ดˆ ํ›„์— ๊ฒฐ๊ณผ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์•„๊นŒ ์‚ดํŽด๋ณธ Boolean-based SQLi ์ฒ˜๋Ÿผ

SELECT * FROM users WHERE user_id = 42; IF(EXISTS(SELECT TOP 1 *
  FROM sysobjects
  WHERE id=(SELECT TOP 1 id
    FROM (SELECT TOP 1 id 
      FROM sysobjects 
      ORDER BY id) 
    AS subq
    ORDER BY id DESC)
  AND ascii(lower(substring(name, 1, 1))) = 'a'))
  WAITFOR DELAY '0:0:5'

์กฐ๊ฑด๋ฌธ๊ณผ ์กฐํ•ฉํ•˜๋ฉด ํ…Œ์ด๋ธ”์ด a๋กœ ์‹œ์ž‘ํ•  ๋•Œ 5์ดˆ ํ›„์— ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค. ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๊ธฐ๊นŒ์ง€ ๋”œ๋ ˆ์ด ๋˜๋Š” ์‹œ๊ฐ„์ด ์–ผ๋งˆ์ธ์ง€๋ฅผ ๋ณด๊ณ  ์กฐ๊ฑด๋ฌธ์ด ์ฐธ์ด์—ˆ๋Š”์ง€ ๊ฑฐ์ง“์ด์—ˆ๋Š”์ง€๋ฅผ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋‹ค.

SQL ์ธ์ ์…˜ ๋ฐฉ์–ด

๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•˜๋Š” ๊ฐ’์„ SQL์— ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค. ์œ„์—์„œ ์‚ดํŽด๋ณด์•˜๋˜ ์˜ˆ์ œ๋“ค์€ ๋‹จ์ˆœํ•˜๊ฒŒ ๋ฌธ์ž์—ด concatenation ์—ฐ์‚ฐ์„ ํ†ตํ•ด SQL๋กœ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ์ด๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ์ธ์ ์…˜ ๊ณต๊ฒฉ์— ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ๋œ๋‹ค.

Input ๊ฒ€์ฆ

ํด๋ผ์ด์–ธํŠธ ์ธก, ์„œ๋ฒ„ ์ธก ๋ชจ๋‘์—์„œ ์ž…๋ ฅ๊ฐ’์ด ํ—ˆ์šฉ๋œ ๋ฒ”์œ„ ๋‚ด์˜ ๊ฐ’์ธ์ง€ ๊ฒ€์ฆํ•˜๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

Prepared Statement ์‚ฌ์šฉ

Prepared Statement๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์ฟผ๋ฆฌ์˜ ํ…œํ”Œ๋ฆฟ์ด ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ง€๊ณ  ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์€ ํ…œํ”Œ๋ฆฟ ์•ˆ์— ์ƒ์ˆ˜ ๊ฐ’ ํ˜•ํƒœ๋กœ ๊ฐ’์ด ์ง€์ •๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ๊ณต๊ฒฉ ์ฟผ๋ฆฌ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค๊ณ  ํ•˜๋”๋ผ๋„ ๋‹จ๋ฌธ ๋ฌธ์ž์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— SQL๋กœ ์ธ์‹๋˜์ง€ ์•Š๋Š”๋‹ค.

Last updated