๐ SQL Injection ์ทจ์ฝ์ ๊ฐ์ ์ธ ์กฐ์น ์ ๋ฆฌ (๋ณด์ ๊ฐ์ ์ฌ๋ก)
1. SQL Injection ์ทจ์ฝ์ ๊ฐ์
๐ด ๋ฌธ์
- MyBatis์์ ${} ์ฌ์ฉ์ผ๋ก ์ฌ์ฉ์ ์ ๋ ฅ์ด SQL์ ์ง์ ์ฝ์ ๋จ
AND B.MBER_NM LIKE '%${searchKeyword}%'
AND B.HNF_NO_TMP IN (${hnfNoTmp})
๐ข ๊ฐ์
- #{} ๋ฐ์ธ๋ฉ์ผ๋ก PreparedStatement ์ ์ฉ
- IN ์ ์ <foreach>๋ก ์์ ํ๊ฒ ์ฒ๋ฆฌ
AND B.MBER_NM LIKE CONCAT('%', #{searchKeyword}, '%')
AND B.HNF_NO_TMP IN
<foreach collection="hnfNoTmpList" item="item" open="(" separator="," close=")">
#{item}
</foreach>
๐ก ํต์ฌ ํฌ์ธํธ
- ${} → ๋ฌธ์์ด ์นํ (์ทจ์ฝ)
- #{} → ๋ฐ์ธ๋ ๋ณ์ (์์ )
2. LIKE / REGEXP ๊ฒ์ ์ ๋ณด์ ์ฒ๋ฆฌ
๐ด ๋ฌธ์
- ์์ผ๋์นด๋ ๋ฐ ์ ๊ท์ ์ฌ์ฉ ์ ์ฌ์ฉ์ ์ ๋ ฅ์ด ๊ทธ๋๋ก ๋ฐ์๋จ
LIKE '%${bizNm}%'
REGEXP '${value}'
๐ข ๊ฐ์
- #{} ๋ฐ์ธ๋ฉ ์ ์ฉ
- %, _ escape ์ฒ๋ฆฌ ๋ฐ ESCAPE ์ฌ์ฉ
- ํ์ ์ Pattern.quote()๋ก ์ ๊ท์ ๋ฌด๋ ฅํ
AND B.BIZ_NM LIKE CONCAT('%', REPLACE(REPLACE(#{bizNm}, '%', '\\%'), '_', '\\_'), '%') ESCAPE '\'
AND A.MBER_LEVEL REGEXP #{safeValue}
๐ก ํต์ฌ ํฌ์ธํธ
- LIKE → wildcard escape ํ์
- REGEXP → ์ ๋ ฅ๊ฐ ๊ฒ์ฆ ๋๋ literal ์ฒ๋ฆฌ ํ์
3. ๋์ ์ปฌ๋ผ ์ฌ์ฉ ์ SQL Injection ๋ฐฉ์ง
๐ด ๋ฌธ์
WHERE ${vrfcColumnNm} = #{vrfcUniqueNo}
- ์ปฌ๋ผ๋ช ์ ${}๋ก ์ง์ ์นํ → ์ธ์ ์ ๊ฐ๋ฅ
๐ข ๊ฐ์
- ์๋ฒ์์ ํ์ดํธ๋ฆฌ์คํธ ๊ฒ์ฆ
๋๋ <choose>๋ก ๋ถ๊ธฐ ์ฒ๋ฆฌ
<choose>
<when test="column == 'ID'">
WHERE ID = #{vrfcUniqueNo}
</when>
</choose>
๐ก ํต์ฌ ํฌ์ธํธ
- ์ปฌ๋ผ๋ช /ํ ์ด๋ธ๋ช ์ ๋ฐ์ธ๋ฉ ๋ถ๊ฐ → ๋ฐ๋์ ๊ฒ์ฆ ํ์
4. XSS (Cross-Site Scripting) ๋ฐฉ์ง
๐ด ๋ฌธ์
${item.entrpsNm}
innerHTML = data;
๐ข ๊ฐ์
- JSP: fn:escapeXml() ์ ์ฉ
- JS: innerHTML ๋์ textContent
- ํ์ ์ DOMPurify ์ ์ฉ
<c:out value="${fn:escapeXml(item.entrpsNm)}"/>
element.textContent = value;
๐ก ํต์ฌ ํฌ์ธํธ
- HTML ์ถ๋ ฅ ์ escape ํ์
- innerHTML ์ฌ์ฉ ์ sanitizing ํ์
5. ์์ธ ์ฒ๋ฆฌ ๋ฐ ๋ก๊ทธ ๋ฏผ๊ฐ์ ๋ณด ์ ๊ฑฐ
๐ด ๋ฌธ์
e.printStackTrace();
LOGGER.error("ERROR", e.getMessage());
- ์ฝ์ ์ถ๋ ฅ ๋ฐ ๋ฉ์์ง์ ๋ฏผ๊ฐ์ ๋ณด ํฌํจ ๊ฐ๋ฅ
๐ข ๊ฐ์
LOGGER.error("Exception occurred", e);
๋๋
LOGGER.debug("IGNORED exception occurred");
๐ก ํต์ฌ ํฌ์ธํธ
- printStackTrace() ๊ธ์ง
- e.getMessage() ์ง์ ์ถ๋ ฅ ์ง์
- ๋ก๊ทธ์๋ ์ฌ์ฉ์ ์ ๋ ฅ ํฌํจ ๊ธ์ง
๐ ๊ธฐ์ ์์ฝ
- MyBatis ๊ธฐ๋ฐ ์๋น์ค์์ ${} ์ฌ์ฉ์ผ๋ก ๋ฐ์ ๊ฐ๋ฅํ SQL Injection ์ทจ์ฝ์ ์ #{} ๋ฐ์ธ๋ฉ ๋ฐ <foreach> ๊ตฌ์กฐ๋ก ๊ฐ์
- LIKE/REGEXP ๊ฒ์ ์ wildcard ๋ฐ ์ ๊ท์ ์ ๋ ฅ๊ฐ์ escape ๋ฐ ๊ฒ์ฆ ์ฒ๋ฆฌํ์ฌ ๋ณด์ ๊ฐํ
- JSP/JavaScript ์์ญ์์ XSS ์ทจ์ฝ์ ์ ๊ฑฐ (escapeXml, textContent ์ ์ฉ)
- ์์ธ ์ฒ๋ฆฌ ๋ก๊น ๊ตฌ์กฐ ๊ฐ์ ์ ํตํด ๋ฏผ๊ฐ์ ๋ณด ๋ ธ์ถ ๋ฐฉ์ง ๋ฐ ์ด์ ๋ก๊ทธ ๋ณด์์ฑ ํฅ์
'์ผ > JAVA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| JSP EL vs <c:out> ์ฐจ์ด ๋ฐ XSS ๋์ ์ ๋ฆฌ (0) | 2026.03.02 |
|---|---|
| JSP/JSTL์์ ํ์ผ๋ช ํ์ฅ์ ์ ๊ฑฐ ์ฒ๋ฆฌ (0) | 2026.03.02 |
| JSP์์ ํน์ URL ํฌํจ ์ฌ๋ถ์ ๋ฐ๋ฅธ ์กฐ๊ฑด ๋ถ๊ธฐ ์ฒ๋ฆฌ (0) | 2026.03.02 |
| JSP ๋ถ๋ฆฌ ๊ตฌ์กฐ์์ ์ ํ๋ ์นดํ ๊ณ ๋ฆฌ๋ฅผ <title>์ ๋์ ์ผ๋ก ๋ฐ์ํ๊ธฐ (0) | 2026.03.02 |
| java16.stream.aggregate (0) | 2023.05.30 |