๐ SQL Injection
๋ง์ ์ฌ์ดํธ์์ ํผ์ ์ด์ฉํ ๋ก๊ทธ์ธ, ๊ฒ์๊ธ ์์ฑ ๋ฑ์ ๋ง์ด ๋ณผ ์ ์๋ค. SQL Injection์ ์ ๋ ฅ ํผ์ SQL ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๊ฒ์ผ๋ก, ์ด๋ฌํ ๊ฐ๋จํด ๋ณด์ด๋ ํ์๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ์ ํฐ ์ํฅ์ ์ค ์ ์๋ค. (e.g ํจ์ค์๋์ ์ ์ฉ์นด๋์ ๊ฐ์ ๊ฐ์ธ์ ๋ณด ํ์ทจ)
โ๏ธ SQL Injection ๊ณผ์
1. HTTP request๋ฅผ ์ฌ์ฉํ๋ ์ ๋ ฅ ํผ์ ํตํด ์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ์ ๋ฐ๋๋ค.
2. ์ด๋, ์ฝ๋์ SQL ์ฝ๋๋ฅผ ์ฝ์ ํ๋ค. ์๋ฅผ ๋ค์ด ' OR 1 = 1'๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ์ฝ์ ํ์ฌ WHERE ์ ์ ํญ์ ์ฐธ์ผ๋ก ๋ง๋ ๋ค.
3. ์น ์๋ฒ๋ ์ฌ์ฉ์์ ์์ฒญ์ ๋ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๋ฌํ๋ค.
4. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ ๋ฌ๋ฐ์ SQL ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ค.
5. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค. SQL Injection์ ์ํด ๋ ธ์ถ๋๋ฉด ์ ๋๋ ๋ฐ์ดํฐ๊ฐ ๋ ธ์ถ๋๊ณ ์ด๋ฅผ ์ ์ฉํ๋ค.
๐ SQL Injection ๋ฐฉ์ด
SQL Injection์ ๋ฐฉ์ดํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด์.
โ๏ธ ๋งค๊ฐ ๋ณ์ํ ์ฟผ๋ฆฌ (Parameterized Statements) ์ฌ์ฉ
๋ง์ฝ ๋ค์๊ณผ ๊ฐ์ด ์ฟผ๋ฆฌ๋ฌธ์ ์์ฑํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์คํ๋๊ธฐ ์ ์ ์ด๋ฏธ ๊ตฌ์กฐํ ๋๊ณ , ํญ์ ์ฐธ์ด ๋๋ ์ฟผ๋ฆฌ๋ฅผ ๋์ง์ผ๋ก์จ ๋ชจ๋ ์ฌ์ฉ์์ ๋ํ ์ ๋ณด๋ฅผ ์ถ๋ ฅํ ์ ์๋ค.
Connection conn = DriverManager.getConnection(URL, ID, PASS);
Statement stmt = conn.createStatement();
// concat์ ์ด์ฉํ ์ฟผ๋ฆฌ ์์ฑ
String sql = "SELECT * FROM users WHERE email = '" + email + "'";
// ์ฟผ๋ฆฌ ์คํ
ResultSet results = stmt.executeQuery(sql);
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋งค๊ฐ ๋ณ์ํ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ๋งค๊ฐ ๋ณ์ํ ์ฟผ๋ฆฌ๋ ์ฟผ๋ฆฌ์ ๋งค๊ฐ ๋ณ์(placeholder)๋ฅผ ์ฌ์ฉํ์ฌ ๋์ ์ผ๋ก ๊ฐ์ ์ ๋ฌํ๋ ๊ฒ์ ๋งํ๋ค. ๋ค์ ์ฝ๋์ฒ๋ผ PreparedStatement๋ฅผ ์ด์ฉํ๋ฉด SQL Injection์ ๋ฐฉ์งํ ์ ์๋ค.
// ๋ฐ์ดํฐ ๋ฒ ์ด์ค ์ฐ๊ฒฐ
Connection conn = DriverManager.getConnection(URL, ID, PASS);
// ์ฟผ๋ฆฌ๋ฌธ ์ค๋น
String sql = "SELECT * FROM user WHERE email = ?";
// prepared statement ์ค๋น
PreparedStatement stmt = conn.prepareStatement(sql);
// ํ๋ผ๋ฏธํฐ ๊ฐ ๋ฐ์ธ๋ฉ
stmt.setString(1, "user@naver.com");
์ฌ๊ธฐ์ ์๋ฌธ์ด stmt.setString(1, "'1'='1'") ๋๊ธฐ๋ฉด ๊ฒฐ๊ตญ์ SQL Injection์ด ๋๋๊ฑฐ ์๋๊ฐ ์ถ์๋ฐ, ๊ทธ๋ ์ง ์๋ค !. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ์ ๋งค๊ฐ ๋ณ์ํ๋ ์ฟผ๋ฆฌ๋ ๋ฌธ์์ด๋ก ํด์ํ์ง ์๊ณ , ๊ฐ์ผ๋ก ์ทจ๊ธํ๋ค. ์ข ๋ ์์ธํ ๋งํ๋ฉด ๋งค๊ฐ ๋ณ์ํ๋ ์ฟผ๋ฆฌ๋ SQL ์ฟผ๋ฆฌ๋ฌธ์ ์ฟผ๋ฆฌ๋ก์ ์ ๋ฌ๋๊ณ ์ดํ์ ๋์ ์ผ๋ก ๊ฐ์ ์ง์ด๋ฃ๋๋ค. ๋ฐ๋ผ์ DBMS๋ ์ฟผ๋ฆฌ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ถ๋ฆฌํ ์ ์์ผ๋ฉฐ SQL Injection์ ๋ฐฉ์งํ ์ ์๋ค.
โ๏ธ Object Relational Mapping (ORM) ์ฌ์ฉ
ORM์ด๋ ๊ฐ์ฒด์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ ๋ณํ์ ์๋ํํด์ฃผ๋ ๊ธฐ์ ์ ๋งํ๋ฉฐ, ํํ ์ฌ์ฉ๋๋ JPA๊ฐ ORM์ด๋ผ๊ณ ํ ์ ์๋ค. ORM์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ฟผ๋ฆฌ๋ฌธ์ ์์ฑํ์ง ์๊ณ ์ด ORM ๊ธฐ์ ์ด ์์ฑํด์ค๋ค. ์ด๋, ๋๋ถ๋ถ์ ORM ๊ธฐ์ ์ ๋งค๊ฐ ๋ณ์ํ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค.
ํ์ง๋ง ORM์ ์ฌ์ฉํ๋๋ผ๋ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ์์ฑํ๋ ๊ฒฝ์ฐ์๋ SQL Injection์ ๋ ธ์ถ๋ ์ ์์ผ๋ฉฐ, ํนํ ๋ฌธ์์ด์ concatํ ๋ ์กฐ์ฌํด์ผ ํ๋ค.
โ๏ธ ์ด์ค์ผ์ดํ ๋ฌธ์ ์ฌ์ฉ
์ฟผ๋ฆฌ์ ์ ์ฉ๋ ๋ฌธ์์ด(์ญ์ฌ๋์, ์์ ๋ฐ์ดํ ๋ฑ)์ ์ด์ค์ผ์ดํ ๋ฌธ์์ด๋ก ๋ฐ๊พธ๋ ๋ฐฉ๋ฒ๋ ์์ผ๋ฉฐ ๋ง์ ์ธ์ด๋ค์ด ํ์ค ํจ์๋ก ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ณ ์๋ค. ํ์ง๋ง SQL Injection์ด ๋ฐ์ดํ๋ ์ญ์ฌ๋์๋ก๋ง ์ด๋ฃจ์ด์ง์ง ์๊ธฐ ๋๋ฌธ์ ์์ ํ ๋ง์์ฃผ์ง๋ ๋ชปํ๋ค.
"SELECT * FROM user WHERE id = " + id;
๋ฌธ์์ด ์ฐ๊ฒฐ์ ํตํด id๊ฐ์ ๊ทธ๋๋ก ์ฐ๊ฒฐํ๊ธฐ ๋๋ฌธ์ '1; DROP TABLE user' ์ ๊ฐ์ SQL Injection์ ํ ์ ์๋ค.
โ๏ธ ์ ๋ ฅ ๊ฐ ์ ์
์ ๋ ฅ ๊ฐ์์ ์ ์ฌ์ ์ธ ์ ์ฑ ์ฝ๋๋ ์ทจ์ฝํ ๋ฌธ์์ด์ ์ ๊ฑฐํ๋ ๊ฒ๋ ํ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ๋ ์ ์๋ค.
- ์ด์ค์ผ์ดํ ์ฒ๋ฆฌ
- ๋ฌธ์์ด ํํฐ๋ง : ์ ๋ ฅ ๊ฐ์ ์ ํฉํ์ง ์์ ๋ฌธ์๋ ๋ฌธ์์ด ํจํด์ ํํฐ๋งํ์ฌ ์ ๊ฑฐํ๋ค. (HTML ํ๊ทธ, ์คํฌ๋ฆฝํธ ์ฝ๋, SQL ์์ฝ์ด ๋ฑ)
- ํ์ ๊ฒ์ฌ : ์ ๋ ฅ ๊ฐ์ ๋ฒ์ ๋๋ ์ ์ฝ ์กฐ๊ฑด์ ๊ฒ์ฌํ๋ค.