2023-02-19 node.js_17

2023. 2. 19. 20:54공부 중/Node.js


 

 

WEB2 - Node.js - 생활코딩

수업소개 이 수업은 JavaScript를 이용해서 Node.js를 제어해 동적으로 HTML 코드를 생성하는 웹애플리케이션을 만드는 방법에 대한 수업입니다.  수업대상 예를들어 1억개의 페이지로 이루어진 웹사

opentutorials.org

생활코딩 node.js 강의 정리

 


0. 보안

 

보안 위협을 체험하고 이에 대한 경각심 느끼기.

 

들어오는 정보와 나가는 정보를 특히 조심하고 의심하는 자세를 가지자.

 


1. 입력에 대한 보안

 

가. URL을 통해서 허용되지 않는 파일에 대한 접근

 

우리는 URL을 파싱해서 파일을 읽어오는 코드를 작성한 적 있다.

fs.readFile(`data/${queryData.id}`, "utf-8", function (err, description) {...});

 

만약 우리가 root 디렉터리에 공개되면 안 되는 파일(ex. password.js)이 있다고 가정한다면 아래와 같은 url을 입력하면 어떻게 될까?

http://loaclhost:3000/?id=../password.js

우리는 어디까지나 ./data 디렉터리 하위에 있는 파일에 대해서만 접근할 거라고 생각했다.

 

하지만 queryData.id의 값에 ../이 포함되면서 ./data 디렉터리보다 상위의 디렉터리에 존재하는 파일에 접근할 수 있게 된다.

 

이는 querystring(id)의 값에 path(../)값이 들어갈 수 있기에 생긴 문제다.

 

 

나. path,parse()

 

querystring(id)의 값에서 path(../)값이 들어갈 수 없게 하면 해결할 수 있다.

 

 

Path | Node.js v19.6.1 Documentation

Path# Source Code: lib/path.js The node:path module provides utilities for working with file and directory paths. It can be accessed using: const path = require('node:path'); Windows vs. POSIX# The default operation of the node:path module varies based on

nodejs.org

 

> const path = require('path');
> path.parse('../password.js');
{
  root: '',
  dir: '..',
  base: 'password.js',
  ext: '.js',
  name: 'password'
}

이렇게 path모듈의 parse라는 메서드를 활용하면 순수한 파일 이름만 얻을 수 있다.

 

우리는 base만 사용하면 된다.

 

let filteredId = path.parse(queryData.id).base;
fs.readFile(`data/${filteredId}`, "utf-8", function (err, description) {...});

꼼꼼히 하려면 사실 여기서 사용자가 입력한 모든 입력들에 대해서 sanitize를 할 필요가 있다. (description에 대해서도)

 

하지만 언제까지나 프레임워크를 사용하지 않고 개발할 것은 아니기에 시간을 아끼도록 하겠다.

 


2. 출력에 대한 보안

 

입력에 대한 보안을 가볍게 살펴보았으니 이젠 출력에 대한 보안을 알아보자.

 

가. XSS

 

이번 시간에 예시로서 다룰 보안 취약점은 XSS다.

 

XSS(Cross-site scripting)란 웹 애플리케이션에서 많이 나타나는 취약점의 하나로 웹사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점이다. 이름이 CSS가 아닌 이유는 웹 기술인 CSS와 헷갈릴 수 있어서다.

 

 

본문의 script 태그를 웹 브라우저가 텍스트가 아닌 html tag로 인식해서 발생한 문제다.

 

출처 : https://ko.wikipedia.org/wiki/사이트스크립팅

 


나. npm sanitize-html

 

본문의 script 태그를 웹 브라우저가 html tag가 아닌 텍스트로 인식하도록 하자.

 

npm으로 다른 사람이 만든 package를 사용해서 원하는 기능을 빠르게 구현할 수 있다.

 

물론 모든 package가 안전한 것은 아니니깐 알아서 걸러 써야 한다.

 

npm init
//package.json 생성

npm에서는 패키지를 package.json이라는 파일로 관리한다.

 

//package.json
{
  "name": "study_nodejs",
  "version": "0.0.0",
  "description": "test version",
  "main": "main.js",
  "directories": {
    "lib": "lib"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "tiredI",
  "license": "ISC",
  "dependencies": {
    "sanitize-html": "^2.10.0"
  }
}
npm install sanitize-html

정상적으로 설치된다면 node_modules라는 디렉터리가 생성된다.

 

 

그 안에 우리가 설치한 sanitize-html과 그 dependencies가 위치한다.

 

공식문서를 통해서 사용법을 익힐 수 있다.

 

 

sanitize-html

Clean up user-submitted HTML, preserving allowlisted elements and allowlisted attributes on a per-element basis. Latest version: 2.10.0, last published: 2 days ago. Start using sanitize-html in your project by running `npm i sanitize-html`. There are 1494

www.npmjs.com

 

// 기본적인 사용법
const sanitizeHtml = require('sanitize-html');
// ./node_modules 디렉터리는 따로 지정하지 않앙도 된다. 이미 약속되어있다.

let dirty = "<script>alert('nyan')</script>";
let clean = sanitizeHtml(dirty);

 

//예외적인 상황을 설정할 수 있다.
const clean = sanitizeHtml(dirty, {
  allowedTags: [ 'b', 'i', 'em', 'strong', 'a' ],
  allowedAttributes: {
    'a': [ 'href' ]
  },
  allowedIframeHostnames: ['www.youtube.com']
});
//공식문서에서 Default options을 확인할 수 있다.

우리가 화면에 출력할 정보 중 sanitize할 것은 titledescription이다.

 

let sanitizedTitle = sanitizeHtml(title);
let sanitizedDesc = sanitizeHtml(description);
...
let html = template.HTML(sanitizedTitle,list, control, sanitizedDesc);
...

정보를 화면에 보여주는 create과 update를 구현하는 코드를 위와 같은 맥락으로 수정한다.

 

출처 : https://web-front-end.tistory.com/3

출처 : https://docs.npmjs.com/cli/v8/commands/npm-install

 


'공부 중 > Node.js' 카테고리의 다른 글

[Jest] node.js 테스트 프레임워크  (0) 2023.03.01
[Javascript] Promise  (0) 2023.03.01
2023-02-18 node.js_16  (0) 2023.02.18
2023-02-13 node.js_15  (0) 2023.02.13
2023-02-13 node.js_14  (0) 2023.02.13