Skip to content

Latest commit

ย 

History

History
140 lines (85 loc) ยท 5.66 KB

SQL-Injection.md

File metadata and controls

140 lines (85 loc) ยท 5.66 KB

SQL Injection

์ž‘์„ฑ์ž : ๊น€์šฐ์˜

์ฃผ์ œ์„ ์ • ์ด์œ 

์•ž์œผ๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๋ฉฐ ํ•ญ์ƒ ํ•„์ˆ˜์ ์œผ๋กœ ๊ณ ๋ คํ•ด์•ผํ•˜๋Š” ๋ณด์•ˆ ์ทจ์•ฝ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ธฐ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ์นจํ•ด์‚ฌ๊ณ  ์ข…๋ฅ˜์ธ SQL Injection ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์— ๋Œ€ํ•ด ๊ฐ„๋žตํ•˜๊ฒŒ ์ •๋ฆฌํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

SQL Injection

SQL Injection์„ ๋ง๊ทธ๋Œ€๋กœ ํ’€์ดํ•˜๋ฉด "SQL ์ฃผ์ž…(์‚ฝ์ž…)"์ž…๋‹ˆ๋‹ค.

SQL ์ธ์ ์…˜์ด๋ž€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ (์ฃผ๋กœ ์›น ํ”„๋กœ๊ทธ๋žจ์„ ๋Œ€์ƒ์œผ๋กœ ์ผ์–ด๋‚˜์ง€๋งŒ DB๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ํ”„๋กœ๊ทธ๋žจ์„ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.)์˜ ๋ณด์•ˆ ์ƒ์˜ ํ—ˆ์ ์„ ์˜๋„์ ์œผ๋กœ ์ด์šฉํ•ด, ์•…์˜์ ์ธ SQL๋ฌธ์„ ์‹คํ–‰ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋น„์ •์ƒ์ ์œผ๋กœ ์กฐ์ž‘ํ•˜๋Š” ์ฝ”๋“œ ์ธ์ ์…˜ ๊ธฐ๋ฒ•์„ ๋œปํ•ฉ๋‹ˆ๋‹ค.

์‹ค์Šต ํ™˜๊ฒฝ ๊ตฌ์„ฑ

  1. user ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    create database user;
  2. user ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    use user;
  3. user_table ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    create table `user_table` (
        `id` varchar(10) not null,
        `password` varchar(20) not null
    ) ENGINE=InnoDB DEFAULT CHARSET `utf8`;
  4. user_table ์— ์‹ค์Šต์„ ์œ„์šฉํ•œ ์ž„์‹œ USER๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    insert into user_table (`id`, `password`) value ("Hello", "world");
    insert into user_table (`id`, `password`) value ("admin", "sdajfkljasldkjf");
    insert into user_table (`id`, `password`) value ("xeros", "testtest1234");

์œ„ ๊ณผ์ •์„ ๊ฑฐ์ณ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์กฐํšŒํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

select * from user_table;

์‹œ๋‚˜๋ฆฌ์˜ค 1) Node.js ๋ฐฑ์—”๋“œ ํ”„๋กœ๊ทธ๋žจ ์„ค๊ณ„

์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€์—์„œ ์•„์ด๋””, ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ ํ›„ POST ์š”์ฒญ์‹œ MySQL ์„œ๋ฒ„๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ„๋„์˜ ๋ณด์•ˆ์ด ์ ์šฉ๋˜์ง€ ์•Š์€์ฑ„ SQL๋ฌธ์„ ์ „์†กํ•˜๋Š” Node.js ๋ฐฑ์—”๋“œ ํ”„๋กœ๊ทธ๋žจ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

SELECT user FROM user_table WHERE id='[์ž…๋ ฅํ•œ ์•„์ด๋””]' AND password='[์ž…๋ ฅํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ]';

์ด๋Ÿฌํ•œ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Node.js ๋ฐฑ์—”๋“œ ํ”„๋กœ๊ทธ๋žจ์€ ์ž…๋ ฅ๋ฐ›์€ ID, PASSWORD๋ฅผ ์šฐ์„  ์œ„ SQL๋ฌธ์„ ์ด์šฉํ•ด ์กฐํšŒํ•˜๊ณ  ๊ฒ€์ƒ‰๋˜๋Š” ๊ฒฐ๊ณผ๊ฐ’์ด ์žˆ๋‹ค๋ฉด, ํ•ด๋‹น ์•„์ด๋””๋กœ ์‚ฌ์šฉ์ž๋ฅผ ๋กœ๊ทธ์ธ์‹œํ‚จ ๋’ค Session์„ ๋ฐœ๊ธ‰ํ•˜๋„๋ก ์ž‘์„ฑ๋˜์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‹œ๋‚˜๋ฆฌ์˜ค 2) ์ •์ƒ์ ์ธ ์ ‘๊ทผ

๋งŒ์•ฝ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ์ž๋ผ๋ฉด ID, PASSWORD๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž…๋ ฅํ• ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•„์ด๋””: xeros
ํŒจ์Šค์›Œ๋“œ: testtest1234

์œ„์™€ ๊ฐ™์ด ์ž…๋ ฅํ•  ๊ฒฝ์šฐ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” SQL๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

SELECT * FROM user_table WHERE id='xeros' AND password='testtest1234';

์ด ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ ๊ฒฐ๊ณผ๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์ž…๋ ฅ๊ฐ’์ค‘ ID ํ˜น์€ PASSWORD ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ๋‹ค๋ฅด๊ฒŒ ์ž…๋ ฅํ–ˆ์„ ๊ฒฝ์šฐ์—๋Š” ์กฐํšŒ๋˜์ง€ ์•Š๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‹œ๋‚˜๋ฆฌ์˜ค 2) ์•…์˜์ ์ธ ์ ‘๊ทผ

์ด๋ฒˆ์—” SQL Injection ๊ณต๊ฒฉ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ ์ ‘๊ทผํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์•„์ด๋””: admin
ํŒจ์Šค์›Œ๋“œ: ' OR '1' = '1

์œ„ POST ์š”์ฒญ์˜ SQL๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

SELECT * FROM user_table WHERE id='admin' AND password=' ' OR '1' = '1';

์œ„ SQL๋ฌธ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์•…์˜์ ์ธ SQL๋ฌธ์˜ ์‹คํ–‰๋˜๊ฒŒ๋˜๋ฉด, DB์—์„œ๋Š” ๋ชจ๋“  ๊ฒฐ๊ณผ๊ฐ’์„ ์ถœ๋ ฅ ๋ฐ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

๊ณต๊ฒฉ ๊ตฌ๋ฌธ์ด ์„ฑ๋ฆฝ๋˜๋Š” SQL ์งˆ์˜๋ฌธ์˜ where์ ˆ ์ดํ›„๋ฅผ ์‚ดํŽด๋ณด๋ฉด id='admin' AND password=' ' OR '1' = '1' ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ์—์„œ AND ์—ฐ์‚ฐ์€ OR ์—ฐ์‚ฐ๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋น ๋ฅด๊ธฐ๋•Œ๋ฌธ์— ๋จผ์ € ์‹คํ–‰๋˜์–ด๋ฒ„๋ฆฌ๊ณ  '1' = '1'์ด๋ผ๋Š” ๊ตฌ๋ฌธ, ์ฆ‰ True๊ฐ€ ๋ฐ˜ํ™˜๋˜๊ธฐ๋•Œ๋ฌธ์— ๊ฒฐ๊ณผ์ ์œผ๋กœ ์œ„ ๊ตฌ๋ฌธ์€ ํ•ญ์ƒ ์ฐธ์ด๊ธฐ์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์‹œํ์–ด์ฝ”๋”ฉ์ด ๋˜์–ด์žˆ์ง€ ์•Š์€ ์šฐ๋ฆฌ์˜ Node.js ๋ฐฑ์—”๋“œ ํ”„๋กœ๊ทธ๋žจ์€ ์œ„ ๋กœ๊ทธ์ธ ์š”์ฒญ์— ๋Œ€ํ•œ DB์˜ ๋ฐ˜ํ™˜๊ฐ’์ด ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ •์ƒ์ ์ธ ์œ ์ €๋กœ ์ธ์‹ํ•˜์—ฌ ๋กœ๊ทธ์ธ์„ ์‹œ์ผœ์ฃผ๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ์‹œ๋กœ ์œ„๋Œ€ํ•œ ์บ์ธ ๋น„๋Š” ๊ด€๋ฆฌ์ž, ์ผ๋ฐ˜ํšŒ์› ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€์™€ DB ํ…Œ์ด๋ธ”์ด ๋ถ„๋ฆฌ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€์—์„œ SQL Injection ๊ธฐ๋ฒ•์ด ์„ฑ๊ณตํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€๋ฅผ ์žฅ์•…๋‹นํ•˜๊ณ  ๋ชจ๋“  ํšŒ์› ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต๊ฒฉ์ž๊ฐ€ ์ทจ๋“ํ•  ์ˆ˜ ์žˆ๊ฒŒ๋˜๋Š” ๋ณด์•ˆ ์นจํ•ด์‚ฌ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

์•„์ง SQL์ด ๋ฏธ์ˆ™ํ•˜์—ฌ ๊ธฐ๋ณธ์ ์ธ ์˜ˆ์ œ๋งŒ ๊ฐ€์ ธ์™”์ง€๋งŒ, ์ด ์™ธ์—๋„ SQL Injection์€ JOIN์ด๋‚˜ DROP๋“ฑ ๋‹ค์–‘ํ•œ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๊ณต๊ฒฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์ด๋Ÿฌํ•œ SQL ๊ณต๊ฒฉ ๋ช…๋ น ๊ตฐ์ง‘์„ ์ž๋™์œผ๋กœ ํ…Œ์ŠคํŒ…ํ•ด์ฃผ๋Š” ํˆด ์—ญ์‹œ๋„ ์กด์žฌํ•˜๋ฉฐ, ๋ฆฌ๋ˆ…์Šค(์ฃผ๋กœ ์นผ๋ฆฌ)์—์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ฐฐํฌ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

SQL Injector

๋ฐฉ์–ด ๋ฐฉ๋ฒ•

๊ณต๊ฒฉ๋‹นํ–ˆ์„๋•Œ ๋ฐœ์ƒํ•˜๋Š” ํ”ผํ•ด์— ๋น„ํ•ด ๋ฐฉ์–ด ๋ฐฉ๋ฒ•์€ ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

Node.js์˜ ๊ฒฝ์šฐ escape() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋ฐฉ์–ด ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉฐ, Node.js ์ด์™ธ์— ๋‹ค๋ฅธ ๋ฐฑ์—”๋“œ ์–ธ์–ด๋“ค๋„ ๋Œ€๋ถ€๋ถ„ ์ด๋Ÿฌํ•œ escape ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

const id = <์‚ฌ์šฉ์ž๋กœ ๋ถ€ํ„ฐ ์ž…๋ ฅ๋ฐ›์€ ๊ฐ’>;
const sql = 'SELECT * FROM user_table WHERE id=' + connection.escape(id);
connection.query(sql, function(err, rows) {
  ...
});