Node.js

App - 출력정보에 대한 보안

수업소개

출력정보에서 발생할 수 있는 보안적인 이슈를 살펴보겠습니다. 

 

 

 

강의 1

 

 

 

강의2

 

 

강의3

 

 

 

소스코드

main.js (변경사항)

var http = require('http');
var fs = require('fs');
var url = require('url');
var qs = require('querystring');
var template = require('./lib/template.js');
var path = require('path');
var sanitizeHtml = require('sanitize-html');

var app = http.createServer(function(request,response){
    var _url = request.url;
    var queryData = url.parse(_url, true).query;
    var pathname = url.parse(_url, true).pathname;
    if(pathname === '/'){
      if(queryData.id === undefined){
        fs.readdir('./data', function(error, filelist){
          var title = 'Welcome';
          var description = 'Hello, Node.js';
          var list = template.list(filelist);
          var html = template.HTML(title, list,
            `<h2>${title}</h2>${description}`,
            `<a href="/create">create</a>`
          );
          response.writeHead(200);
          response.end(html);
        });
      } else {
        fs.readdir('./data', function(error, filelist){
          var filteredId = path.parse(queryData.id).base;
          fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
            var title = queryData.id;
            var sanitizedTitle = sanitizeHtml(title);
            var sanitizedDescription = sanitizeHtml(description, {
              allowedTags:['h1']
            });
            var list = template.list(filelist);
            var html = template.HTML(sanitizedTitle, list,
              `<h2>${sanitizedTitle}</h2>${sanitizedDescription}`,
              ` <a href="/create">create</a>
                <a href="/update?id=${sanitizedTitle}">update</a>
                <form action="delete_process" method="post">
                  <input type="hidden" name="id" value="${sanitizedTitle}">
                  <input type="submit" value="delete">
                </form>`
            );
            response.writeHead(200);
            response.end(html);
          });
        });
      }
    } else if(pathname === '/create'){
      fs.readdir('./data', function(error, filelist){
        var title = 'WEB - create';
        var list = template.list(filelist);
        var html = template.HTML(title, list, `
          <form action="/create_process" method="post">
            <p><input type="text" name="title" placeholder="title"></p>
            <p>
              <textarea name="description" placeholder="description"></textarea>
            </p>
            <p>
              <input type="submit">
            </p>
          </form>
        `, '');
        response.writeHead(200);
        response.end(html);
      });
    } else if(pathname === '/create_process'){
      var body = '';
      request.on('data', function(data){
          body = body + data;
      });
      request.on('end', function(){
          var post = qs.parse(body);
          var title = post.title;
          var description = post.description;
          fs.writeFile(`data/${title}`, description, 'utf8', function(err){
            response.writeHead(302, {Location: `/?id=${title}`});
            response.end();
          })
      });
    } else if(pathname === '/update'){
      fs.readdir('./data', function(error, filelist){
        var filteredId = path.parse(queryData.id).base;
        fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
          var title = queryData.id;
          var list = template.list(filelist);
          var html = template.HTML(title, list,
            `
            <form action="/update_process" method="post">
              <input type="hidden" name="id" value="${title}">
              <p><input type="text" name="title" placeholder="title" value="${title}"></p>
              <p>
                <textarea name="description" placeholder="description">${description}</textarea>
              </p>
              <p>
                <input type="submit">
              </p>
            </form>
            `,
            `<a href="/create">create</a> <a href="/update?id=${title}">update</a>`
          );
          response.writeHead(200);
          response.end(html);
        });
      });
    } else if(pathname === '/update_process'){
      var body = '';
      request.on('data', function(data){
          body = body + data;
      });
      request.on('end', function(){
          var post = qs.parse(body);
          var id = post.id;
          var title = post.title;
          var description = post.description;
          fs.rename(`data/${id}`, `data/${title}`, function(error){
            fs.writeFile(`data/${title}`, description, 'utf8', function(err){
              response.writeHead(302, {Location: `/?id=${title}`});
              response.end();
            })
          });
      });
    } else if(pathname === '/delete_process'){
      var body = '';
      request.on('data', function(data){
          body = body + data;
      });
      request.on('end', function(){
          var post = qs.parse(body);
          var id = post.id;
          var filteredId = path.parse(id).base;
          fs.unlink(`data/${filteredId}`, function(error){
            response.writeHead(302, {Location: `/`});
            response.end();
          })
      });
    } else {
      response.writeHead(404);
      response.end('Not found');
    }
});
app.listen(3000);

 

댓글

댓글 본문
작성자
비밀번호
  1. leesj020925@naver.com
    npm install -S sanitize-html
    인스톨 과정에서 에러가 발생하는게 경로중에 띄어쓰기가 포함된 디렉토리가 있으면 안되나요? 이고잉님과 마찬가지로 바탕화면에 nodejs 폴더를 생성하고 지금까지 강좌를 따라왔습니다.


    C:\Users\Stephen Lee\Desktop\nodejs>npm install -S sanitize-html
    npm WARN nodejs@1.0.0 No description
    npm WARN nodejs@1.0.0 No repository field.

    npm ERR! path C:\Users\Stephen Lee\Desktop\nodejs\node_modules\domutils
    npm ERR! code ENOENT
    npm ERR! errno -4058
    npm ERR! syscall rename
    npm ERR! enoent ENOENT: no such file or directory, rename 'C:\Users\Stephen Lee\Desktop\nodejs\node_modules\domutils' -> 'C:\Users\Stephen Lee\Desktop\nodejs\node_modules\.domutils.DELETE'
    npm ERR! enoent This is related to npm not being able to find a file.
    npm ERR! enoent

    npm ERR! A complete log of this run can be found in:
    npm ERR! C:\Users\Stephen Lee\AppData\Roaming\npm-cache\_logs\2018-11-28T10_13_00_967Z-debug.log

    보시기 번거롭겠지만 발생된 에러 부분입니다.
    아톰에서도 일부분만 설치됐습니다.
  2. 일단시작하고본다
    크으으 감사합니다 이고잉님!!
  3. jo_onc
    어쩌다보니 삽질 2시간만에 성공했습니다 하핳...
    강의 감사합니다^^
  4. fed-gren
    말씀하신게 맞다고 생각되는게,

    출력정보에 대한 보안은
    사용자가 입력한 정보를 출력할 때 발생하는 문제에 대한 보안이라는 주제라고 이해했습니다.

    문제를 발생시키는 코드를 보면 html로 들어가는 부분에 사용자가 script 태그를 써서 자바스크립트로 동작시키면서
    그 정보를 입력한건 문제가 없으나 출력할 때 문제를 일으키죠.

    그래서 nomadlife님이 말씀하신대로, 표시할 때 sanitizing을 하는게 맞습니다. 저장된 정보에도 script태그는 남아있으니까요.:)
    대화보기
    • nomadlife
      'update'시에는 sanitizing을 안해도 문제가 없길래, 궁금해서 한참 생각해 봤는데, 입력정보를 sanitizing 시킨게 아니라, 표시할때만 sanitizing을 해서 그런거 같은데, 제가 맞게 이해한건가요? 앞서 토픽에서 말씀하신 $ lt $gt 로 바꾸는거는 적용이 안된거죠?
    • metallsk
      학습량이 늘어나면서, 이곳저곳 버퍼가 생기지만 역시 재미있습니다. 항상 감사합니다. egoing님~!!
    • 감사합니다.
    • Seo Yun Seok Tudoistube
      보안에 대한 특강을 부탁드립니다.
      sanitize-html 을 꼭 써야겠습니다.
      감사합니다^^!
    graphittie 자세히 보기