์์ฑ์ : ๊น์ฐ์
์์ผ๋ก ๊ฐ๋ฐ์ ํ๋ฉฐ ํญ์ ํ์์ ์ผ๋ก ๊ณ ๋ คํด์ผํ๋ ๋ณด์ ์ทจ์ฝ์ ์ด๋ผ๊ณ ์๊ฐํ๊ธฐ๋๋ฌธ์ ๊ฐ์ฅ ๋น๋ฒํ๊ฒ ๋ฐ์ํ๋ ์นจํด์ฌ๊ณ ์ข ๋ฅ์ธ SQL Injection ๊ณต๊ฒฉ ๊ธฐ๋ฒ์ ๋ํด ๊ฐ๋ตํ๊ฒ ์ ๋ฆฌํด๋ณด์์ต๋๋ค.
SQL Injection์ ๋ง๊ทธ๋๋ก ํ์ดํ๋ฉด "SQL ์ฃผ์ (์ฝ์ )"์ ๋๋ค.
SQL ์ธ์ ์ ์ด๋ ์์ฉ ํ๋ก๊ทธ๋จ (์ฃผ๋ก ์น ํ๋ก๊ทธ๋จ์ ๋์์ผ๋ก ์ผ์ด๋์ง๋ง DB๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ํ๋ก๊ทธ๋จ์ ๋์์ผ๋ก ํฉ๋๋ค.)์ ๋ณด์ ์์ ํ์ ์ ์๋์ ์ผ๋ก ์ด์ฉํด, ์ ์์ ์ธ SQL๋ฌธ์ ์คํํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋น์ ์์ ์ผ๋ก ์กฐ์ํ๋ ์ฝ๋ ์ธ์ ์ ๊ธฐ๋ฒ์ ๋ปํฉ๋๋ค.
-
user
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์์ฑํฉ๋๋ค.create database user;
-
user
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ ํํฉ๋๋ค.use user;
-
user_table
ํ ์ด๋ธ์ ์์ฑํฉ๋๋ค.create table `user_table` ( `id` varchar(10) not null, `password` varchar(20) not null ) ENGINE=InnoDB DEFAULT CHARSET `utf8`;
-
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;
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ํ์ด์ง์์ ์์ด๋, ๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ ํ POST
์์ฒญ์ MySQL ์๋ฒ๋ก ๋ค์๊ณผ ๊ฐ์ด ๋ณ๋์ ๋ณด์์ด ์ ์ฉ๋์ง ์์์ฑ SQL๋ฌธ์ ์ ์กํ๋ Node.js ๋ฐฑ์๋ ํ๋ก๊ทธ๋จ์ด ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
SELECT user FROM user_table WHERE id='[์
๋ ฅํ ์์ด๋]' AND password='[์
๋ ฅํ ๋น๋ฐ๋ฒํธ]';
์ด๋ฌํ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ Node.js ๋ฐฑ์๋ ํ๋ก๊ทธ๋จ์ ์ ๋ ฅ๋ฐ์ ID, PASSWORD๋ฅผ ์ฐ์ ์ SQL๋ฌธ์ ์ด์ฉํด ์กฐํํ๊ณ ๊ฒ์๋๋ ๊ฒฐ๊ณผ๊ฐ์ด ์๋ค๋ฉด, ํด๋น ์์ด๋๋ก ์ฌ์ฉ์๋ฅผ ๋ก๊ทธ์ธ์ํจ ๋ค Session์ ๋ฐ๊ธํ๋๋ก ์์ฑ๋์์ ๊ฒ์ ๋๋ค.
๋ง์ฝ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ์๋ผ๋ฉด ID, PASSWORD๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ ๋ ฅํ ๊ฒ์ ๋๋ค.
์์ด๋: xeros
ํจ์ค์๋: testtest1234
์์ ๊ฐ์ด ์ ๋ ฅํ ๊ฒฝ์ฐ ๋ฐฑ์๋ ์๋ฒ์์ ์ฒ๋ฆฌํ๋ SQL๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
SELECT * FROM user_table WHERE id='xeros' AND password='testtest1234';
์ด ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ฒ ๋ ๊ฒฝ์ฐ ๊ฒฐ๊ณผ๊ฐ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋ง์ฝ ์ ๋ ฅ๊ฐ์ค ID ํน์ PASSWORD ๋ ์ค ํ๋๋ผ๋ ๋ค๋ฅด๊ฒ ์ ๋ ฅํ์ ๊ฒฝ์ฐ์๋ ์กฐํ๋์ง ์๊ณ ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ ๊ฒ์ ๋๋ค.
์ด๋ฒ์ 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 ๊ณต๊ฒฉ ๋ช ๋ น ๊ตฐ์ง์ ์๋์ผ๋ก ํ ์คํ ํด์ฃผ๋ ํด ์ญ์๋ ์กด์ฌํ๋ฉฐ, ๋ฆฌ๋ ์ค(์ฃผ๋ก ์นผ๋ฆฌ)์์ ์ฌ์ฉ๊ฐ๋ฅํ๋๋ก ๋ฐฐํฌ๋๊ณ ์์ต๋๋ค.
๊ณต๊ฒฉ๋นํ์๋ ๋ฐ์ํ๋ ํผํด์ ๋นํด ๋ฐฉ์ด ๋ฐฉ๋ฒ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค.
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) {
...
});