๐Ÿ•น๏ธ 5. ํฌ๋กœ์Šค ์‚ฌ์ดํŠธ ์Šคํฌ๋ฆฝํŒ…

๐Ÿ•น๏ธ ๋ชจ์˜ํ•ดํ‚น ์ฒดํ—˜ ๋„์ „

๐Ÿ•น๏ธ ๋ชจ์˜ํ•ดํ‚น ์ฒดํ—˜ ๋”ฐ๋ผํ•˜๊ธฐ โ–ถSTEP_1) ๊ฒ€์ƒ‰ํ•œ ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธ

STEP_2) ์Šคํฌ๋ฆฝํŠธ ๊ตฌ๋ฌธ์„ ์‚ฝ์ž…ํ•˜์—ฌ ๊ฒ€์ƒ‰ ์‹œ ํŠน์ • ๋ฌธ์ž๊ฐ€ ํ•„ํ„ฐ๋ง๋˜๋Š” ๊ฒƒ์„ ํ™•์ธ

STEP_3) ํ•„ํ„ฐ๋ง ๋˜๋Š” ๋ฌธ์ž์—ด์„ ์šฐํšŒํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ ๊ตฌ๋ฌธ ์‚ฝ์ž… ํ›„ ๊ฒ€์ƒ‰

STEP_4) ์Šคํฌ๋ฆฝํŠธ ๊ตฌ๋ฌธ์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜์–ด FLAG ๊ฐ’์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Œ


O ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฐ’์— ๋Œ€ํ•œ ํ•„ํ„ฐ๋ง์ด ์ œ๋Œ€๋กœ ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์„ ๊ฒฝ์šฐ, ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ์ด ๊ฐ€๋Šฅํ•œ ํผ(์›น ๋ธŒ๋ผ์šฐ์ € ์ฃผ์†Œ ์ž…๋ ฅ ๋˜๋Š” ๊ฒŒ์‹œํŒ ๋“ฑ)์— ์•…์˜์ ์ธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜์—ฌ ์‚ฌ์šฉ์ž ์„ธ์…˜ ๋„์šฉ, ์•…์„ฑ์ฝ”๋“œ๋ฅผ ์œ ํฌํ•  ์ˆ˜ ์žˆ๋Š” ์ทจ์•ฝ์ 

# XSS ๊ณต๊ฒฉ ๋ฐฉ์‹

- Reflected XSS

: ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’ ๋‚ด ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํฌํ•จํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ๊ณผ ํ•จ๊ป˜ ์ „์†กํ•˜๋Š” ๋ฐฉ์‹ 

: ์ „๋‹ฌ๋œ ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์„œ๋ฒ„์—์„œ ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์‘๋‹ต์— ๋ฐ˜์˜๋˜์–ด ์‹คํ–‰๋˜๋Š” ์ทจ์•ฝ์ 

- Stored XSS

: ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์›น ์„œ๋ฒ„์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ํŒŒ์ผ ๋“ฑ์— ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹

: ์ €์žฅ๋œ ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์— ์ง€์†์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š” ์ทจ์•ฝ์ 


O ๊ทผ๊ฑฐ ์ž๋ฃŒ

โ˜ž ์ฃผ์š”์ •๋ณดํ†ต์‹ ๊ธฐ๋ฐ˜์‹œ์„ค ๊ธฐ์ˆ ์  ์ทจ์•ฝ์  ๋ถ„์„ ํ‰๊ฐ€ ์ƒ์„ธ ๊ฐ€์ด๋“œ(p.681)

โ˜ž OWASP TOP10 2021


O ํŒ๋‹จ ๊ธฐ์ค€

์–‘ํ˜ธ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ธ์ˆ˜ ๊ฐ’์— ๋Œ€ํ•œ ๊ฒ€์ฆ ๋ฐ ํ•„ํ„ฐ๋ง์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒฝ์šฐ
์ทจ์•ฝ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฐ’์— ๋Œ€ํ•œ ๊ฒ€์ฆ ๋ฐ ํ•„ํ„ฐ๋ง์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์œผ๋ฉฐ, HTML ์ฝ”๋“œ๊ฐ€ ์ž…๋ ฅ ๋ฐ ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ


O ์ ๊ฒ€ ๋ฐฉ๋ฒ•

- ๊ฒŒ์‹œํŒ ๋“ฑ์— ์•…์˜์ ์ธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜์—ฌ ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํ•„ํ„ฐ๋ง ๋˜๋Š”์ง€ ํ™•์ธ

# ์˜ˆ์ œ ์Šคํฌ๋ฆฝํŠธ : <script>alert("xss")</script>, <IMG SRC=alert("XSS")>


O ์กฐ์น˜ ๋ฐฉ๋ฒ•

- ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฐ’์—์„œ ์ž…๋ ฅ ๊ฐ€๋Šฅํ•œ ๋ฌธ์ž ์ œํ•œํ•˜๊ณ  ๊ทธ ์™ธ ๋ฌธ์ž ํ•„ํ„ฐ๋ง ์ ์šฉ

: ํ•„ํ„ฐ๋ง ๋Œ€์ƒ : GET ์งˆ์˜ ๋ฌธ์ž์—ด, POST ๋ฐ์ดํ„ฐ, ์ฟ ํ‚ค, URL ๋“ฑ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €์™€ ์›น ์„œ๋ฒ„๊ฐ€ ์ฃผ๊ณ ๋ฐ›๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ

- ๊ฒŒ์‹œํŒ ๋‚ด HTML ํฌ๋งท์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋„๋ก ์„ค์ •

: HTML ํฌ๋งท์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ ํ—ˆ์šฉ๋œ ํƒœ๊ทธ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๊ณ , XSS์— ์•…์šฉ๋  ์†Œ์ง€๊ฐ€ ์žˆ๋Š” ํƒœ๊ทธ๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ œ๊ฑฐ ๋ฐ ํŠน์ • ๋ฌธ์ž๋กœ ์น˜ํ™˜ํ•˜๋„๋ก ์„ค์ •

- JAVA, Springboot ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋ณด์•ˆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ ์šฉ

: Spring Security, OWASP Java Encoder ๋“ฑ ์šด์˜/๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ์ ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํŒ๋‹จ ํ›„ ์ ์šฉ ์กฐ์น˜

# ํ•„ํ„ฐ๋ง ๋Œ€์ƒ ํŠน์ˆ˜๋ฌธ์ž ์˜ˆ์‹œ โ–ถ
๋ณ€๊ฒฝ ์ „๋ณ€๊ฒฝ ํ›„
<&lt;
>&gt;
(&#40;
)&#41;
#&#35;
&&amp;
{&#123;
}&#125;


# ์ˆ˜์ • ํ•„ํ„ฐ๋ง ๋Œ€์ƒ ๋ฌธ์ž์—ด ์˜ˆ์‹œ โ–ถ
<script><object><applet><form><embed>
<iframe><frame><base><body><frameset>
<html><img><layer><a href><meta>
<p><style><xxx src>document. cookiejavascript


# ํ•„ํ„ฐ๋ง ๋Œ€์ƒ ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์˜ˆ์‹œ โ–ถ
copycutfocusinfocusout
fullscreenchangefullscreenerroronabortonafterprint
onanimationend
onanimationiteration
onanimationstart
onbeforeprint
onbeforeunload
onblur
oncanplay
oncanplaythrough
onchange
onclick
oncontextmenu
ondblclick
ondrag
ondragend
ondragenter
ondragleave
ondragover
ondragstart
ondrop
ondurationchange
onended
onerror
onfocus
onhashchange
onkeyup
onload
onloadeddata
onloadedmetadata
onloadstart
onmessage
onmousedownonmouseenter
onmouseleave
onmousemove
onmouseout
onmouseover
onmouseup
onmousewheel
onoffline
ononline
onopen
onpagehide
onpageshow
onpause
onplay
onplaying
onpopstate
onprogress
onratechange
onreset
onresize
onscroll
onsearch
onseeked
onseeking
onselect
onstalled
onstorage
onsubmit
onsuspend
ontimeupdate
ontoggle
ontransitionend
onunload
onvolumechange
onwaiting
onwheel
paste
show
touchcancel
touchendtouchmove
touchstart


# HTML DOM Events ์ถœ์ฒ˜: https://www.w3schools.com/jsref/dom_obj_event.asp


O ์‹œํ์–ด ์ฝ”๋”ฉ(Secure Coding) ์˜ˆ์‹œ

# ASP โ–ถ
.....
<%
    If use_html Then // HTML tag๋ฅผ ์‚ฌ์šฉ
        memo = Server.HTMLEncode(memo) //HTML tag๋ฅผ ๋ชจ๋‘ ์ œ๊ฑฐ

        // ํ—ˆ์šฉํ•  HTML tag๋งŒ ๋ณ€๊ฒฝํ•œ๋‹ค
        memo = replace(memo, "&lt;p&gt;", "<p>")
        memo = replace(memo, "&lt;P&gt;", "<P>")
        memo = replace(memo, "&lt;br&gt;", "<br>")
        memo = replace(memo, "&lt;BR&gt;", "<BR>")
        //HTML tag๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•  ๊ฒฝ์šฐ
    Else 
       memo = Server.HTMLEncode(memo) // HTML encoding
       memo = replace(memo, "<", "&lt")
       memo = replace(memo, ">", "&gt")
    End If

    Response.write "๊ฒŒ์‹œ๋ฌผ ๋‚ด์šฉ-" & memo & "<BR>"
.....


# JSP โ–ถ
.....
<BODY>
<%
ย  ย  String user_agent = request.getHeader("USER-AGENT");
ย  ย  // HTTP HEADER ์ค‘ USER_AGENT๋ฅผ ๋ณ€๊ฒฝ ํ•˜์—ฌ ํฌ๋กœ์Šค์‚ฌ์ดํŠธ ์Šคํฌ๋ฆฝํŠธ ๊ณต๊ฒฉํ•˜๋Š” ๊ฒƒ์„ ์ฐจ๋‹จํ•œ๋‹ค
    // HTML tag๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์ œ๊ฑฐํ•œ๋‹ค.
ย  ย  user_agent = user_agent.replaceAll("<","&lt");
    user_agent = user_agent.replaceAll(">","&gt");
    out.print("์ง€๊ธˆ ์‚ฌ์šฉํ•˜๊ณ  ๊ณ„์‹  ");
    out.print(user_agent);
    out.print(" ๋ธŒ๋ผ์šฐ์ €๋กœ๋Š” ์‚ฌ์ดํŠธ ์ ‘์†์ด ๋ถˆ๊ฐ€๋Šฅ ํ•ฉ๋‹ˆ๋‹ค.");
%>
</BODY>


# XSS ๋ฐฉ์ง€ ๊ณตํ†ต ๋ชจ๋“ˆ โ–ถ

- XSSfilter.java 

if(CONTENT != NULL){
    CONTENT = CONTENT.replaceAll("<","&lt;,");
    CONTENT = CONTENT.replaceAll(">","&gt;,");
    CONTENT = CONTENT.replaceAll("&","&amp;,");
    CONTENT = CONTENT.replaceAll("\"","&quot;,");
} 
else {
    return;
}
.....

- Filter ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„

public class FirstFilter implements javax.servlet.Filter {

    public void init(FilterConfig filterConfig) throws ServletException {
    }

ย    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        chain.doFilter(request, response);ย 
    } 
 
    public void destroy() {
ย  ย  }
}

- web.xml

<web-app>
ย  ย  <filter>
        <filter-name>XSS</filter-name>
        <filter-class>XSSFilter</filter-class>
        <init-param>
      
ย  ย  ย <param-name>paramName</param-class>
           <param-value>value<param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>XSS</filter-name>
        <uri-pattern>/*</uri-patten>
    </filter-mapping>
</web-app>