[Etc] ๐ฃ SQL Injection
์ ์์ ์ธ ์ฌ์ฉ์๊ฐ SQL ์ฟผ๋ฆฌ์ ์ฝ๋๋ฅผ ์ฝ์ ํด DB์ ๋ณด๋ฅผ ํ์ทจํ๊ฑฐ๋ ์กฐ์ํ๋ ๊ฒ์ ๋ปํ๋ SQL Injection์ ๋ํด ์์๋ณด์.
SQL Injection์ด๋?
SQL Injection์ด๋, ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๊ฐ์ ํตํด ์๋ ์๋ํ์ง ์์ SQL๋ฌธ์ ์คํํ๊ฒ ๋ง๋ค์ด
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ๋ฅผ ํ์ทจํ๊ฑฐ๋ ์กฐ์ํ๋ ๊ณต๊ฒฉ
๐ ์์ (Spring ์ฐ๊ธฐ ์ ์ผ๋ฐ JDBC ์ฝ๋ ๊ธฐ์ค):
String sql = "SELECT * FROM users WHERE username = '" + username + "'";
๋ง์ฝ username
์ ์๋์ ๊ฐ์ ๊ฐ์ ์
๋ ฅํ๋ฉด?
' OR '1'='1
๊ทธ๋ฌ๋ฉด ์ฟผ๋ฆฌ๊ฐ ์ด๋ ๊ฒ ๋ฐ๋:
SELECT * FROM users WHERE username = '' OR '1'='1'
โ ๋ชจ๋ ์ ์ ์ ๋ณด๊ฐ ๋ค ์กฐํ๋จ ๐ฑ
โ ๋น๋ฐ๋ฒํธ ์์ด ๋ก๊ทธ์ธ๋ ๊ฐ๋ฅํด์ง
๐ Spring ๊ด์ ์์ SQL Injection ๋ฐฉ์ง๋ฒ
โ 1. JDBC ์ง์ ์ฌ์ฉ ์: PreparedStatement ํ์!
String sql = "SELECT * FROM users WHERE username = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username); // ์๋์ผ๋ก ๋ฌธ์์ด escape ์ฒ๋ฆฌ
์ด๋ ๊ฒ ํ๋ฉด ' OR '1'='1
๊ฐ์ ์
๋ ฅ๋ ๊ทธ๋ฅ ๋ฌธ์์ด๋ก ์ธ์๋๋ฏ๋ก ์์ ํ๋ค.
โ 2. Spring JDBC Template ์ฌ์ฉ ์
String sql = "SELECT * FROM users WHERE username = ?";
User user = jdbcTemplate.queryForObject(sql, new Object[]{username}, userRowMapper);
์ฌ๊ธฐ์๋ ?
๋ฅผ ์ฌ์ฉํด์ ๋ฐ์ธ๋ฉํ๋ฉด PreparedStatement๊ฐ ์ ์ฉ๋๋ฏ๋ก ์์ ํ๋ค.
โ 3. JPA / Spring Data JPA ์ฌ์ฉ ์
JPA๋ SQL์ ์ง์ ์์ฑํ์ง ์๊ณ ์ํฐํฐ ์ค์ฌ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก SQL Injection์ ๊ฐํจ!
๐ธ ์์:
User user = userRepository.findByUsername(username);
์ด๋ฐ ๋ฐฉ์์ ๋ด๋ถ์ ์ผ๋ก PreparedStatement๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์์ ํจ.
๐ธ ์ปค์คํ JPQL ์ฌ์ฉ ์์๋ ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ ํ์!
@Query("SELECT u FROM User u WHERE u.username = :username")
User findByUsername(@Param("username") String username);
โ
:username
ํํ๋ก ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉํ๋ฉด OK
โ ์๋์ฒ๋ผ ๋ฌธ์์ด ์ง์ ์ฐ๊ฒฐํ๋ฉด ์ํ:
@Query("SELECT u FROM User u WHERE u.username = '" + username + "'")
๐จ Spring ๋ฐฐ์ฐ๋ ์ ์ฅ์์ ์กฐ์ฌํ ํฌ์ธํธ ์์ฝ
์ํฉ | ์์ ํ ๋ฐฉ๋ฒ | ์ฃผ์ํ ์ |
---|---|---|
JDBC ์ง์ ์ฌ์ฉ | PreparedStatement | ๋ฌธ์์ด ์ง์ ์ฐ๊ฒฐ โ |
JdbcTemplate | ? ์๋ฆฌ ๋ฐ์ธ๋ฉ ์ฌ์ฉ | ์ฟผ๋ฆฌ ์กฐํฉ โ |
JPA / Spring Data JPA | ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ (:param ) | JPQL ๋ฌธ์์ด ์ง์ ๋ถ์ด๊ธฐ โ |
QueryDSL | ์์ ์์ (ํ์ ๊ธฐ๋ฐ ์ฟผ๋ฆฌ) | - |
์ฌ์ฉ์ ์ ๋ ฅ๊ฐ ์ฒ๋ฆฌ | ์ ๋ ฅ ๊ฒ์ฆ, ๊ธธ์ด ์ ํ | ํํฐ ์์ด ๋ฐ๋ก ์ฌ์ฉ โ |
๐ฏ ๋ง๋ฌด๋ฆฌ ์์ฝ
- SQL Injection = ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๊ฐ์ ํตํด ์ ์ฑ SQL ์คํ
- Spring์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก PreparedStatement ๋ฐฉ์์ด๋ฏ๋ก ์ ์ฐ๋ฉด ์์ ํจ
- ํ์ง๋ง ์ง์ ์ฟผ๋ฆฌ ์ง๊ฑฐ๋, ๋ฌธ์์ด๋ก SQL์ ์กฐํฉํ๋ ๊ฒฝ์ฐ ์ฃผ์!
- ORM(JPA) + ํ๋ผ๋ฏธํฐ ๋ฐ์ธ๋ฉ ๋ฐฉ์์ผ๋ก ์์ฑํ๋ฉด ๊ฑฐ์ ๋๋ถ๋ถ ์์ ํ๊ฒ ๋ง์ ์ ์์