Skip to content

Latest commit

Β 

History

History
89 lines (70 loc) Β· 5.15 KB

File metadata and controls

89 lines (70 loc) Β· 5.15 KB

1. XSS(cross-site-scripting) 곡격 κ°œμš”

μ •μ˜

XSSλŠ” HTML μΈμ μ…˜μ˜ μΌμ’…μœΌλ‘œ μ›ΉνŽ˜μ΄μ§€μ˜ λ‚΄μš©μ„ λ³€κ²½ν•˜κ±°λ‚˜ ν”Όν•΄μžμ˜ μ›ΉλΈŒλΌμš°μ €μ— μž„μ˜μ˜ μžλ°” 슀크립트λ₯Ό μ‹€ν–‰ν•˜λŠ” 곡격이닀. κ³΅κ²©μžκ°€ μƒλŒ€λ°©μ˜ λΈŒλΌμš°μ €μ— Scriptλ₯Ό μ‹€ν–‰ν•  수 있게 ν•˜μ—¬ μ‚¬μš©μž Session을 κ°€λ‘œμ±„κ±°λ‚˜ μ›Ή μ‚¬μ΄νŠΈ λ³€μ‘°, μ•…μ˜μ  컨텐츠 μ‚½μž…, ν”Όμ‹± 곡격을 ν•  수 μžˆλ‹€. μ›Ήμ‚¬μ΄νŠΈμ—μ„œ 메일 μ£Όμ†Œ, μ‚¬μš©μž ID, λΈ”λ‘œκ·Έ λŒ“κΈ€, 우편번호 λ“±κ³Ό 같은 μ‚¬μš©μžμ˜ 정보λ₯Ό μž…λ ₯ 받은 ν›„ 이λ₯Ό λ‹€μ‹œ λ³΄μ—¬μ£ΌλŠ” κ³Όμ •μ—μ„œ λ°œμƒν•œλ‹€.

image

2. XSS(cross-site-scripting) 곡격 μœ ν˜•

3. λ³΄μ•ˆ λŒ€μ±…

πŸ‘‰ 방법 1. λ¬Έμžμ—΄ μΉ˜ν™˜ν•˜κΈ°

μ™ΈλΆ€ μž…λ ₯값에 μŠ€ν¬λ¦½νŠΈκ°€ μ‚½μž…λ˜μ§€ λͺ»ν•˜λ„둝 λ¬Έμžμ—΄ μΉ˜ν™˜ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€.

πŸ“Œ μΉ˜ν™˜ μ „ : & < > " ' / ( )

πŸ“Œ μΉ˜ν™˜ ν›„ : &amp; &lt; &gt; &quot; &#x27; &#x2F; &#x28; &#x29;둜 μΉ˜ν™˜ν•œλ‹€.

μ•ˆμ „ν•˜μ§€ μ•Šμ€ μ½”λ“œ μ˜ˆμ‹œ (Java)

μ™ΈλΆ€ μž…λ ₯값에 λŒ€ν•˜μ—¬ 검증 없이 화면에 좜λ ₯될 경우 κ³΅κ²©μŠ€ν¬λ¦½νŠΈκ°€ ν¬ν•¨λœ URL을 생성 ν•  수 μžˆμ–΄ μ•ˆμ „ν•˜μ§€ μ•Šλ‹€.(Reflected XSS)

<% String keyword = request.getParameter("keyword"); %>

검색어 : <%=keyword%>

μ•ˆμ „ν•œ μ½”λ“œ μ˜ˆμ‹œ (Java)

μž…λ ₯값에 λŒ€ν•˜μ—¬ 슀크립트 곡격가λŠ₯성이 μžˆλŠ” λ¬Έμžμ—΄μ„ μΉ˜ν™˜ν•œλ‹€.

<% String keyword = request.getParameter("keyword"); %>

keyword = keyword.replaceAll("&", "&amp;");
keyword = keyword.replaceAll("<", "&lt;");
keyword = keyword.replaceAll(">", "&gt;");
keyword = keyword.replaceAll("οΏ¦"", "&quot;");
keyword = keyword.replaceAll("'", "&#x27;");
keyword = keyword.replaceAll("/"", "&#x2F;");
keyword = keyword.replaceAll("(", "&#x28;");
keyword = keyword.replaceAll(")", "&#x29;");
검색어 : <%=keyword%>

μ˜ˆμ‹œ μ½”λ“œ 더보기

πŸ“Œ Java μ‹œνμ–΄ μ½”λ“œ
πŸ“Œ C μ‹œνμ–΄ μ½”λ“œ

πŸ‘‰ 방법 2. ν—ˆμš©λ˜λŠ” HTML νƒœκ·Έλ“€μ„ ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ 필터링

μ‚¬μš©μžκ°€ HTML μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ„λ‘ ν—ˆμš©ν•˜κ²Œ 되면 μžλ°”μŠ€ν¬λ¦½νŠΈ μ—­μ‹œ μ‚¬μš©ν•  수 있게 λ˜λ―€λ‘œ XSS곡격을 μ‰½κ²Œ ν•  수 μžˆλŠ” ν™˜κ²½μ΄ λœλ‹€.

HTMLμ½”λ“œμ—μ„œ μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ‹€ν–‰ν•  수 μžˆλŠ” 방법은 μˆ˜λ„ 없이 λ§ŽμœΌλ―€λ‘œ <script> νƒœκ·Έμ™€ 같은 μ§€μ •λœ νŠΉμ • νŒ¨ν„΄μ„ κ±ΈλŸ¬λ‚΄λŠ” λΈ”λž™λ¦¬μŠ€νŠΈ λ°©μ‹μœΌλ‘œλŠ” XSSλ₯Ό 막기가 μ–΄λ ΅λ‹€.

HTML νƒœκ·Έλ₯Ό ν—ˆμš©ν•˜λŠ” κ²Œμ‹œνŒμ—μ„œλŠ” ν—ˆμš©λ˜λŠ” HTML νƒœκ·Έλ“€μ„ ν™”μ΄νŠΈλ¦¬μŠ€νŠΈλ‘œ λ§Œλ“€μ–΄ ν•΄λ‹Ή νƒœκ·Έλ§Œ μ§€μ›ν•˜λ„λ‘ ν•œλ‹€.

πŸ’‘ μ—¬κΈ°μ„œ 잠깐,

λΈ”λž™λ¦¬μŠ€νŠΈ 필터링 VS ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ 필터링 μ΄λž€?

μž…λ ₯검증을 μœ„ν•œ 방법은 두 가지가 μžˆλ‹€. 즉 ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ(white-list)와 λΈ”λž™λ¦¬μŠ€νŠΈ(black-list)λ₯Ό μ΄μš©ν•˜λŠ” 방법이닀.

  • λΈ”λž™λ¦¬μŠ€νŠΈ 필터링: ν—ˆμš©λ˜μ§€ μ•ŠλŠ” μž…λ ₯ 값에 λŒ€ν•œ 리슀트
  • ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ 필터링: ν—ˆμš© κ°€λŠ₯ν•œ μž…λ ₯ 값에 λŒ€ν•œ 리슀트

ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ, λΈ”λž™λ¦¬μŠ€νŠΈλΌλŠ” μš©μ–΄ λŒ€μ‹  'positive'와 'negative' λ³΄μ•ˆ λ°©λ²•μœΌλ‘œ λΆˆλ €μ§€κΈ°λ„ ν•œλ‹€.

πŸ‘‰ 방법 3. 라이브러리 ν™œμš©

JSTL λ˜λŠ” 잘 μ•Œλ €μ§„ 크둜슀 μ‚¬μ΄νŠΈ 슀크립트 방지 라이브러리λ₯Ό ν™œμš©ν•œλ‹€.

μ•ˆμ „ν•˜μ§€ μ•Šμ€ μ½”λ“œ μ˜ˆμ‹œ (Java)

μ™ΈλΆ€ μž…λ ₯값에 λŒ€ν•˜μ—¬ 검증 없이 λΈŒλΌμš°μ €μ—μ„œ μ‹€ν–‰λ˜λŠ” 경우 μ„œλ²„λ₯Ό κ±°μΉ˜μ§€ μ•ŠλŠ” κ³΅κ²©μŠ€ν¬λ¦½νŠΈκ°€ ν¬ν•¨λœ URL을 생성 ν•  수 μžˆμ–΄ μ•ˆμ „ν•˜μ§€ μ•Šλ‹€. (DOM 기반 XSS)

<script type="text/javascript">
  document.write("keyword:" + <%=keyword%>);
</script>

μ•ˆμ „ν•œ μ½”λ“œ μ˜ˆμ‹œ (Java)

NAVER Lucy-XSS-Filter, OWASP ESAPI, OWASP Java-Encoder-Project λ“±μ˜ XSS 방지 라이브러리λ₯Ό μ‚¬μš©ν•œλ‹€.

<script type="text/javascript">
  document.write("keyword:" +
  <%=Encoder.encodeForJS(Encoder.encodeForHTML(keyword))%>);
</script>

References

XSS 곡격과 λŒ€μ‘λ°©μ•ˆ, 디지털정책연ꡬ = The Journal of digital policy & management v.11 no.12, 2013λ…„, pp.327 – 332, ν™μ„±ν˜ (λ°±μ„λŒ€ν•™κ΅, 정보톡신학뢀 μ •λ³΄λ³΄ν˜Έ 전곡)

크둜슀 μ‚¬μ΄νŠΈ μŠ€ν¬λ¦½νŒ…(XSS) 취약점에 λŒ€ν•œ 곡격과 λ°©μ–΄, λ””μ§€ν„Έμœ΅λ³΅ν•©μ—°κ΅¬ = Journal of digital convergence v.13 no.2 , 2015λ…„, pp.177 – 183, μ΅œμ€μ • (μ„œμšΈμ—¬μžλŒ€ν•™κ΅ μ •λ³΄λ³΄ν˜Έν•™κ³Ό )

ν–‰μ •μ•ˆμ „λΆ€, μ „μžμ •λΆ€ SW 개발·운영자λ₯Ό μœ„ν•œ μ†Œν”„νŠΈμ›¨μ–΄ κ°œλ°œλ³΄μ•ˆ κ°€μ΄λ“œ, 2019. 11