먼저 ReactJS가 설치될 폴더를 하나 생성합니다. 

<예시>

이 생성된 폴더에 ReactJS를 설치할 계획입니다.

 

터미널을 하나 실행합니다. 

윈도우즈 검색에서 cmd 라고 검색해도 아래 그림과 같이 찾을 수 있습니다. 

명령 프롬프트에 아래 그림과 같이 입력하여 create-react-app를 설치합니다. (npm이 아니고 npx 입니다.)

최초 설치시에는 시간이 좀 걸릴 수 있습니다. 

<주의사항 react_01 이라는 프로젝트 명은 대문사를 사용하면 오류가 발생합니다. ex) myReactJS >

npx create-react-app c:\dev\react_01

 

실행 결과 

.

.

.

 

설치가 완료되었다면 이전에 설치한 VSCode를 실행하고 해당 폴더를 열어줍니다. 

예시) c:\dev\react_01

해당 폴더를 선택해준 경우 정상적으로 파일이 자동으로 생성되어 있는 것을 확인할 수 있습니다.

 

Webpack, Babel등을 추가로 설치하여 개발환경을 구성하는데에 초보자에게는 상당한 어려움이 있으나 Create-react-app를 이용하면 환경설정을 쉽게 할 수 있습니다. 

React를 시작하기 위한 준비물로 가장먼저 NodeJS 설치를 먼저해야합니다.  

NodeJS 를 설치하는 이유는 npx를 이용하여 create-react-app를 설치하기 위해서입니다. 

 

https://nodejs.org/ko/

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

https://nodejs.org/ko/

 

 

그리고 코드를 작성하기 위해서 에디터를 설치해야하는데 가장 많이 사용하고 있는 Visual Studio Code(VS Code)를 설치하도록 하겠습니다. 

https://code.visualstudio.com/

 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

https://code.visualstudio.com/

'Web > ReactJS' 카테고리의 다른 글

#04-02. Component를 만들어보자  (0) 2022.12.20
#04-01. Component 란?  (0) 2022.12.20
#03-02.폴더 및 파일의 역할  (0) 2022.12.19
#03-01. Create-react-app 설치 및 오류사항 대응  (0) 2022.12.19
#02. Create-react-app 설치  (0) 2022.12.19

개요

Apache HTTP Server에서 입력값 검증이 미흡하여 발생하는 버퍼오버플로우 취약점(CVE-2021-44790)
공격자가 조작된 요청을 mod_lua*모듈로 처리 할 때 버퍼 오버플로가 가능한 취약점

 

영향받는 버전

Apache HTTP Server 2.4.51 및 이전 버전

 

해결방안

1. 취약점 업데이트 (패치 적용 前 업무시스템의 서비스 영향 검토 후 적용할 것)
    -   2.4.51 및 이전 버전의 경우, 최신 버전(2.4.52) 업그레이드 적용[2]
 
2. 임시 조치방안
    - mod_lua 모듈 非활성화 (디폴트로 비활성화 되어있음)
    ※ 모듈 확인방법 : 소스 트리의 httpd.conf 내 "LoadModule lua_module modules/mod_lua.so" 검색 > 주석 처리

ES6이다 뭐다... 모든브라우저에서 작성한 코드가 동작을 안하는 경우 난감한 상황이 발생 할 수 있다.

그중에 하나가 javascript 작성시 중복제거 코드를 작성했는데 IE에서 동작하지 않는 경우를 볼 수 있다.

 

findindex나 화살표함수(ES6) 문법을 사용하는 코드의 경우 문제가 될 수 있다.

아직까지 IE가 사라지지 않았으므로.. jQuery를 이용한 중복제거 함수를 작성해 보았다.

1
2
3
4
5
6
7
8
9
var valueArr = ["11","22","33","44","11","55","66"]; // 원본배열
var uniqueArr = []; // 중복이 제거된 배열이 생성될 변수
$.each(valueArr, function(k, val){ 
    if($.inArray(val, uniqueArr) === -1){
        uniqueArr.push(val); 
    }
});
 
console.log(uniqueArr);
cs

 

관리자 계정명 관리

 

관리자 계정명 미변경 및 기본유저 로그인 가능할 시 취약하다.

관리자 콘솔 사용시 User name 확인
[4.x / 5.x] - /[Tomcat path]/conf/tomcat-users.xml

 

<tomcat-users> 
<role rolename=""tomcat""/>
  <role rolename=""admin-gui""/>
  <role rolename=""manager-gui""/>
  <role rolename=""role1""/>
  <user username=""autoever"" password=""autoever"" roles=""admin-gui,manager-gui""/>
  <user username=""tomcat"" password=""tomcat"" roles=""tomcat""/>
  <user username=""both"" password=""tomcat"" roles=""tomcat,role1""/>
  <user username=""role1"" password=""tomcat"" roles=""role1""/> </tomcat-users>

[6.x / 7.x / 9.x] - /[tomcat path]/conf/tomcat-users.xml

 

(apt-get 으로 설치한 경우 /etc/tomcat7/tomcat-users.xml에 있을 수 있음)

 

[시스템현황] [ tomcat dir ]\conf\tomcat-users.xml 'tomcat-user' 설정 미존재

 

 

조치사항

 

1. [4.x / 5.x] - 관리자 콘솔 사용시 User name 확인 및 변경

   [6.x / 7.x] – 아래의 설정 파일을 통해 User name 확인 및 변경 설정 파일 : /[Tomcat path]/conf/tomcat-users.xml

 

2. [4.x / 5.x] - 관리자 콘솔의 [User Definition | Users | RoleName]에서 계정명을 설정

 

3. [6.x / 7.x] - 기본 유저와 패스워드를 삭제 또는 주석으로 처리해 주어 기본 유저로의 로그인이 불가능 하도록 권고한다.

 

설정 파일 : /[Tomcat path]/conf/tomcat-users.xml

관리자 콘솔 관리

Default 포트(8080)를 사용하고 있고, 관리자 콘솔 사용시 취약하다.

Tomcat 관리자 콘솔 사용 유무 확인함.
예) http://[Domain]/manager, http://[Domain]/admin/

(단, Tomcat 5.5.x의 버전의 경우 admin을 따로 다운로드 받아 설치하여야 하며
6.0 이상의 버전엔 http://[Domain]/admin/ 자체가 존제하지 않으므로 http://[Domain]/manager 만 확인)

 

 

조치사항

1. Default포트인 8080은 공격자가 유추 할 수 있으므로, 유추할 수 없는 포트로 변경. 번호를 지정하여 사용하기를 권고함 (권장 포트 범위 : 1024~65534)

 

    - 설정 파일 : /[Tomcat path]/conf/server.xml

    - server.xml 파일 변경 후 Tomcat 서버를 Stop하고 다시 start 시켜야 적용됨


2. 필요 시에만 관리자 콘솔 운영을 권고함, 필요한 경우에 한하여 관리자 콘솔을 사용하고 불필요한 경우 프로세스를 종

 

지난 시간에 이어서 자식/형제요소 및 조합 선택자를 알아보도록 하겠습니다.

 

  • 자식요소 선택자 ( > )

selector로 하나의 요소를 지정한 후 > 선택자를 사용하여 자식요소를 지정할 수 있습니다.  1개의 자식요소가 선택되어 집니다. 

$("#myObject > div");

 

  • 자식요소 선택자(복수)

selector로 하나의 요소를 지정한 후 띄워쓰기 후 해당 선택요소를 지정합니다.

$("#myObject div");

$("#myObject div").eq(0); // div tag 요소 중 첫번째 자식요소

 

  • 형제요소 선택자

지정된 myObject 요소의 형제요소를 선택할때 사용 할 수 있습니다. 

$('#myObject + div'); // #myObject 바로 다음 div를 선택합니다.


$('#myObject ~ div'); // #myObject 형제 div를 모두 선택합니다.
$('#myObject ~ div').eq(1);

 

  • 조합 선택자

지난 시간 및 위에 소개된 선택자를 복합적으로 사용하여 요소를 지정할 수 있습니다. 

 

아래의 구성요소중 span #2를 찾을 경우 

<div id="myObject">
	<div> 1번 div </div>
    <div> 2번 div </div>
    <div> 
    	<span> span #1 </span>
        <span> span #2 </span>
    </div>
</div>

다음과 같이 구성하여 요소를 선택 할 수 있습니다. 

$("#myObject div span").eq(1)

 

jQuery에 대해서 업무 중 교육을 할 일이 생겨 정리합니다.

 

  • jQuery를 왜 사용하는 것인가?

   jQuery는 Selector가 없다면 사용을 안 할 수도 있다 라는 생각이 될 정도로 편리한 Selector를 제공합니다. 

   CSS 선택자를 그대로 사용할 수 있어 코드 선택이 매우 간단합니다. 물론 document.querySelector   

   와 document.querySelectorAll이 있기도 하지만 모르는 사람이 더 많을뿐더러 이미 jQuery가 자리 잡은 상황이기

   때문에 jQuery가 개발하는 사람들에게는 더 친숙합니다. 

 

 

 

 

jQuery Selector를 사용함에 있어 몇 가지만 알아도 사용하는 데에는 큰 무리가 없습니다. 

 

 

  • Id로 해당 Object 찾기(#)

단순히 #뒤에 아이디를 입력하여 해당 오브젝트를 선택할 수 있습니다.

//javascript
document.getElementById('objId');

//jQuery
$('#objId');

 

 

  • class로 Object 찾기(.)|

단순히. 뒤에 해당 css class 명을 입력하여 해당 오브젝트를 선택할 수 있습니다. 이때 동일한 class가 여러 개인 경우

. eq(숫자)를 이용하여 해당 인덱스에 해당하는 오브젝트를 선택할 수 있습니다.

 

//javascript
document.getElementsByClassName('your_class_name');

//jQuery
$('.your_class_name');

// 4번째 오브젝트 선택 (0부터 시작)
$('.your_class_name').eq(3);

 

  • tag로 Object 찾기

$() 안에 해당 tag를 입력하여 사용할 수 있습니다. 또한 여러 개의 동일한 tag가 존재하는 경우 eq()를 이용하여 해당 인덱스에 해당하는 오브젝트를 선택할 수 있습니다. 

//javascript
document.getElementsByTagName('table');

//jQuery
$("table");

//첫번째 table
$("table").eq(0);

 

  • 속성으로 Object 찾기( [ ] )

해당 기능은 javascript는 제공하지 않으므로 별도의 함수를 만들어서 사용해야 합니다. 

[ ] 안에 속성명 또는 속성에 해당하는 값의 형태로 작성하여 사용할 수 있습니다. 

//jQuery
$('[type]'); // type 라는 속성을 가진 Object

$('[type="button"]'); // type이 button인 Object

$('[type="button"]').eq(1);

 

 

replace() 함수

  • 자바스크립트에서 특정문자 또는 특수문자를 제거할때 replace() 함수를 사용하는 경우 , #가 여러번 있는 문자열(주민번호,전화번호)을 단순히 replace('#','')로 하면, 처음 #기호만 삭제되고 나머지는 삭제되지 않습니다.
var testStr = "#1#2#3";
testStr.replace("#","");

//결과값 : 1#2#3



replace()함수와 정규식을 활용하여 Java의 replaceAll() 함수와 동일한 기능을 하도록 만들어 보겠습니다. 

var testStr = "#1#2#3";
testStr.replace(/\#/g,"");

//결과값 : 123

해당 코드를 이용하여 replaceAll() 함수를 생성하여 사용하도록 합니다.

 

 

추가내용

  • 자주쓰는 정규식
    • 특정문자 제거(#제거)   : str.replace(/\#/g,'');
    • 앞의 공백 제거           : str.replace(/^\s+/,'');
    • 뒤 공백 제거              : str.replace(/\s+$/,'');
    • 앞 공백 제거              : str.replace(/^\s+|\s+$/g,'');
    • 문자열 내의 공백 제거 : str.replace(/\s/g,'');
    • 줄바꿈 제거               : str.replace(/\n/g,'');
    • 엔터 제거                  : str.replace(/\r/g,'');
    • 0 제거                      : str.replace(/[^(1-9)]/gi,"");

XSS란?

XSS(cross-site scripting)는 웹페이지에 악의적인 스크립트 코드를 주입할 수 있는 취약점이다.

 

XSS(Cross Site Scripting) 방지를 위해 널리 쓰이는 훌륭한 lucy-xss-servlet-filter는 Servlet Filter 단에서 < 등의 특수 문자를 &lt; 등으로 변환해주며, 여러 가지 관련 설정을 편리하게 지정할 수 있어 정말 좋다.

그런데 그 처리가 form-data에 대해서만 적용되고 Request Raw Body로 넘어가는 JSON에 대해서는 처리해주지 않는다는 단점이 있다. 그래서 JSON을 주고 받는 API 서버의 경우에는 직접 처리를 해줘야 한다.

 

즉, Lucy는 RequestParameter관련한 지원만 해준다.

 

 

그래서 이를 보완하기 위해서 여러가지 방법이 있겠지만, 가장 많이 사용되는 방법인 Request를 Wrapping 하여 적용하도록 한다. (기존에 Lucy XSS Filter를 사용하고 있다는 가정하에 작성)

 

준비물 : 2개의 Java Class, web.xml, Lucy XSS Filter

 

# Lucy XSS Filter는 Maven Central Repository 에 배포되어 있다. pom.xml 에 아래와 같이 의존성을 선언한다.

1
2
3
4
5
<dependency>
    <groupId>com.navercorp.lucy</groupId>
    <artifactId>lucy-xss</artifactId>
    <version>X.X.X</version>
</dependency>
cs

 

 

RequestWrapper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
 
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
 
import com.nhncorp.lucy.security.xss.XssFilter;
 
public class RequestWrapper extends HttpServletRequestWrapper {
    private byte[] b;
 
    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        XssFilter filter = XssFilter.getInstance("lucy-xss-sax.xml");
        b = new String(filter.doFilter(getBody(request))).getBytes("UTF-8");
    }
 
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bis = new ByteArrayInputStream(b);
        return new ServletInputStreamImpl(bis);
    }
 
    class ServletInputStreamImpl extends ServletInputStream {
        private InputStream is;
 
        public ServletInputStreamImpl(InputStream bis) {
            is = bis;
        }
 
        public int read() throws IOException {
            return is.read();
        }
 
        public int read(byte[] b) throws IOException {
            return is.read(b);
        }
    }
 
    public static String getBody(HttpServletRequest request) throws IOException {
        String body = null;
       BufferedReader br= null;
       StringBuilder sb= new StringBuilder();
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
               br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = br.read(charBuffer)) > 0) {
                   sb.append(charBuffer, 0, bytesRead);
                }
              
            } else {
               sb.append("");
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (br!= null) {
                try {
                   br.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        body = sb.toString();
        return body;
    }
}
 
cs

 

실제 필터링 기능을 수행하는 Java class이다. 

주의할 부분은 해당 작업을 수행할 경우 한글이 깨져서 chain.doFilter(requestWrapper, response);가 수행될 때 Json 오류가 날 수 있다.

그러므로 br= new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); 항목에 인코딩 설정을 명시해서 해당 오류를 피해 가도록 한다.

 

 

 

RequestBodyXSSFIleter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class RequestBodyXSSFIleter implements Filter {
    private List<String> extUrl;
 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
       RequestWrapper reqWrapper = null;
        String path = ((HttpServletRequest) req).getServletPath();
 
        try {
            if (!extUrl.contains(path)) {
              
               reqWrapper = new RequestWrapper(request);
               chain.doFilter(reqWrapper , response);
            } else {
                chain.doFilter(request, response);
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String excludePattern = filterConfig.getInitParameter("extUrls");
       extUrl = Arrays.asList(excludePattern.split(","));
    }
 
    @Override
    public void destroy() {
    }
}
 
cs

 

requestBody에 XSS Filter를 적용할 경우 Multipart(일반적으로 파일 업로드) 일 때 파일이 손상되는 일이 발생한다.

이를 방지하기위해 파일을 송신하는 URL의 경우 web.xml의 init-param을 이용하여 필터링을 제외할 수 있다.

 

RequestBodyXSSFIleter의 init시 filterConfig에서 해당 파라미터에 접근하여 제외할 URL목록을 콤마(,)로 구분하여 작성 후 필터를 적용하지 않는 방법으로 우회할 수 있다.

 

 

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    <!-- Xss Filter Start -->
    <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>
    
    <filter>
        <filter-name>RequestBodyXSSFilter</filter-name>
        <filter-class>com.your.pkg.path.filter.RequestBodyXSSFIleter</filter-class>
        <init-param>
            <param-name>extUrls</param-name>
            <param-value>/linkUrl1,/linkUrl2,/linkUrl2</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>RequestBodyXSSFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Xss Filter End -->
cs

 

+ Recent posts