JSP

Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(9) - Lucy 라이브러리를 이용한 XSS(크로스사이트 스크립팅) 방어하기

김마리님 2020. 6. 9. 15:42

이전 게시글은 여기 <<

Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(8) - 부트스트랩과 섬머노트를 이용한 글쓰기 페이지 만들기

 

Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(8) - 부트스트랩과 섬머노트를 이용한 글쓰기 페

이전 게시글은 여기 << Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(7) - ajax를 이용한 아이디 중복검사 하기 Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(7) - ajax를 이용한 아이디 중복검�

itstudy-mary.tistory.com

 

XSS(크로스 사이트 스크립팅)이 무엇일까?

XSS는 게시글따위에 악의적인 스크립트 코드를 넣어 서비스 기능을 중지시키는 웹해킹 기법이다. 이 방법은 사이트와 사이트 이동간에 발생하는 해킹방식인데, 단순히 게시글에 스크립트 글씨만 넣는 방식의 간단한(?) 해킹방식인 것처럼, 방어하기도 비교적 쉽다.

 

크로스 사이트 스크립팅의 예시를 보자.

결과적으로 페이지가 먹통이 되어버린다. HTML이 '이 사이트가 아직 스크립트가 끝난 상태가 아님' 이라고 해석하기 때문이다. 

하지만 이 방식은 간단하게 제어가 가능한데, 데이터베이스 내에 들어가는 값들을 HTML Entitiy(HTML 특수코드)로 들어가게 하거나 데이터베이스에서 값을 가져와 송출될때 코드에 영향을 주는 기호를 HTML Entitiy로 변경하면 된다. 이것을 도와주는 라이브러리가 Lucy 라이브러리다. Lucy 라이브러리는 전자의 방식을 도와준다.

 

일단 사용 결과는 다음과 같다.

 

이렇게 특수코드로 변환되서 들어간 것을 볼 수 있다.

 

이제 라이브러리를 사용해보자.

 

익숙한 친구(?) Maven responsity로 들어가보면,

https://mvnrepository.com/

 

Maven Repository: Search/Browse/Explore

Spring Cloud Starter Last Release on Jun 9, 2020

mvnrepository.com

"Lucy"만 검색해도 이만큼 나온다. 익숙한 아이콘이다. 네이버에서 개발한거 맞다.

우리는 서블릿 코드를 이용하기 때문에 서블릿 필터를 다운받는다.

 

들어가서 버전을 선택하면..

이것이 연관된 라이브러리이다. 다 사용해야하기 때문에 다.. 다운받으시면 됩니다.

 

(챱)

앞서서 우리는 서버 XML 필터 이외에 패키지 내에서 동작할 web.xml 필터를 하나 더 만들었었는데, 거기에 적용할 코드는 다음과 같다.

 

- web.xml (blog 패키지 내의 파일)

--
--
--
	<filter-mapping>
		<filter-name>setCharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<filter>
		<filter-name>xssEscapeServletFilter</filter-name>
		<filter-class>com.navercorp.lucy.security.xss.servletfilter.XssEscapeServletFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>xssEscapeServletFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping> 

이 때 주의할 점이, 반드시.. 반드시 CharacterEncoding filter 뒤에 넣어야한다. 인코딩 필터가 입력된 글을 정해진 방식 (ex. utf-8)로 인코딩 하는데, 그 전에 필터를 적용시키면 인코딩이 올바르게 동작하지 않는다.

 

이제 서블릿 필터를 만들어보자.

이건.. Lucy라이브러리 공식 깃허브에 자세히 나와있다 .. ^^ 대기업 최고

https://github.com/naver/lucy-xss-servlet-filter

 

naver/lucy-xss-servlet-filter

Contribute to naver/lucy-xss-servlet-filter development by creating an account on GitHub.

github.com

코드에서 특정 파라메터를 막거나, 특정 uri를 막거나 할 계획은 없으니 싹 날린다(..!)

 

이 파일들은 서블릿에 동작하는 파일이므로 src 내부에 만들어주세용.

 

- lucy-xss-servlet-filter-rule.xml

<?xml version="1.0" encoding="UTF-8"?>

<config xmlns="http://www.navercorp.com/lucy-xss-servlet">
	<defenders>
		<!-- XssPreventer 등록 -->
		<defender>
			<name>xssPreventerDefender</name>
			<class>com.navercorp.lucy.security.xss.servletfilter.defender.XssPreventerDefender
			</class>
		</defender>
	</defenders>

	<!-- XssSaxFilter 등록 -->
	<defender>
		<name>xssSaxFilterDefender</name>
		<class>com.navercorp.lucy.security.xss.servletfilter.defender.XssSaxFilterDefender
		</class>
		<init-param>
			<param-value>lucy-xss-sax.xml</param-value>   <!-- lucy-xss-filter의 sax용 설정파일 -->
			<param-value>false</param-value>        <!-- 필터링된 코멘트를 남길지 여부, 성능 효율상 false 추천 -->
		</init-param>
	</defender>

	<!-- default defender 선언, 필터링 시 지정한 defender가 없으면 여기 정의된 default defender를 
		사용해 필터링 한다. -->
	<default>
		<defender>xssPreventerDefender</defender>
	</default>

	<!-- global 필터링 룰 선언 -->
	<global>
		<params>
			<param name="content" useDefender="false" />
		</params>
	</global>

	<url-rule-set>
		<url-rule>
			<url>/*</url>
			<params>
				<param name="content">
					<defender>xssSaxFilterDefender</defender>
				</param>
			</params>
		</url-rule>
	</url-rule-set>
</config>

 

 

또, 이걸 방어해도 특정 태그나 속성으로 공격하는 경우도 있으므로, 이것도 방어하는 코드도 지정해주자.

 

- lucy-xss-sax.xml

<?xml version="1.0" encoding="UTF-8"?>

<config xmlns="http://www.nhncorp.com/lucy-xss"
	extends="lucy-xss-default-sax.xml">

	<elementRule>
        <element name="p"/>
        <element name="a" />
        <element name="abbr"/>
        <element name="acronym"/>
        <element name="adress"/>
        <element name="applet"/>
        <element name="area"/>
        <element name="b"/>
        <element name="base"/>
        <element name="basefont"/>
        <element name="bdo"/>
        <element name="big"/>
        <element name="blockquote"/>
        <element name="body"/>
        <element name="br"/>
        <element name="button"/>
        <element name="caption"/>
        <element name="center"/>
        <element name="cite"/>
        <element name="code"/>
        <element name="col"/>
        <element name="colgroup"/>
        <element name="dd"/>
        <element name="del"/>
        <element name="dfn"/>
        <element name="dir"/>
        <element name="div"/>
        <element name="dl"/>
        <element name="dt"/>
        <element name="em"/>
        <element name="embed"/>
        <element name="fieldset"/>
        <element name="font"/>
        <element name="form"/>
        <element name="frame"/>
        <element name="frameset"/>
        <element name="h1"/>
        <element name="h2"/>
        <element name="h3"/>
        <element name="h4"/>
        <element name="h5"/>
        <element name="h6"/>
        <element name="head"/>
        <element name="hr"/>
        <element name="html"/>
        <element name="i"/>
        <element name="iframe"/>
        <element name="img"/>
        <element name="input"/>
        <element name="ins"/>
        <element name="isindex"/>
        <element name="kbd"/>
        <element name="label"/>
        <element name="legend"/>
        <element name="li"/>
        <element name="link"/>
        <element name="map"/>
        <element name="marquee"/>
        <element name="menu"/>
        <element name="meta"/>
        <element name="nobr"/>
        <element name="noframes"/>
        <element name="noscript"/>
        <element name="object"/>
        <element name="ol"/>
        <element name="optgroup"/>
        <element name="option"/>
        <element name="p"/>
        <element name="param"/>
        <element name="pre"/>
        <element name="q"/>
        <element name="rt"/>
        <element name="ruby"/>
        <element name="s"/>
        <element name="samp"/>
        <!-- <element name="script"/> -->
        <element name="select"/>
        <element name="small"/>
        <element name="span"/>
        <element name="strike"/>
        <element name="strong"/>
        <element name="style"/>
        <element name="sub"/>
        <element name="sup"/>
        <element name="table"/>
        <element name="tbody"/>
        <element name="td"/>
        <element name="textarea"/>
        <element name="tfoot"/>
        <element name="th"/>
        <element name="thead"/>
        <element name="title"/>
        <element name="tr"/>
        <element name="tt"/>
        <element name="u"/>
        <element name="ul"/>
        <element name="var"/>
        <element name="wbr"/>
        <element name="xml"/>
        <element name="xmp"/>
        
        <!-- HTML5 added at 2012.04.10 Start-->
        <element name="article"/>
        <element name="aside"/>
        <element name="audio"/>
        <element name="bdi"/>
        <element name="canvas"/>
        <element name="command"/>
        <element name="datalist"/>
        <element name="details"/>
        <element name="figcaption"/>
        <element name="figure"/>
        <element name="footer"/>
        <element name="header"/>
        <element name="hgroup"/>
        <element name="keygen"/>
        <element name="mark"/>
        <element name="meter"/>
        <element name="nav"/>
        <element name="output"/>
        <element name="progress"/>
        <element name="rp"/>
        <element name="section"/>
        <element name="source"/>
        <element name="summary"/>
        <element name="time"/>
        <element name="track"/>
        <element name="video"/>
        <!-- HTML5 added at 2012.04.10 End-->
        
        <!-- IE핵 처리를 위해 추가-->
        <element name="IEHackExtension" disable="ture" >
        </element>
    </elementRule>
 
    <attributeRule>
        <attribute name="src">
            <allowedPattern><![CDATA[['"]?\s*http://.*]]></allowedPattern>
        </attribute>
        <attribute name="href">
            <notAllowedPattern><![CDATA[(?i:script)]]></notAllowedPattern>
            <notAllowedPattern><![CDATA[(?i:\.css)]]></notAllowedPattern>
        </attribute>
        <attribute name="style" disable="false" exceptionTagList="a"/> <!-- 2013.12.24 수정 : A 태그는 style 속성에 의한 우회 공격 이슈로 style 속성을 배제힌다. -->
    </attributeRule>


</config>

 

 

 

(Lucy xss 필터에 대한 자세한 내용은 여기<<<)

https://github.com/naver/lucy-xss-filter

 

naver/lucy-xss-filter

Contribute to naver/lucy-xss-filter development by creating an account on GitHub.

github.com

 

반응형