생활코딩

Coding Everybody

코스 전체목록

닫기

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. 김철흥
    2024.01.14
    h1 tag는 sanitize 안됨..
  2. BF_Lee
    230705
  3. 어흥
    230702
  4. 감자
    22.12.05 완료
  5. 당당
    2022.10.29
  6. 아캔두잇
    20220811 완료
  7. 키다리아저씨
    220720 완
  8. toonfac
    220714 오후 4시 40분 완료
  9. 진승범
    감사합니다~
  10. DotGaBi95
    npm으로 sanitize-html 설치하기 전에 pm2에서 main.js 실행시킨 상태면 pm2에서 main.js 재실행 하심 될겁니다.
    pm2 stop main.js
    pm2 start main.js
    아니면 pm2 restart main.js
    이거로도 안되시면
    pm2 save
    pm2 kill
    pm2 resurrect 해보세요!
    저는 그렇게 했더니 되더라구요. sanitize-html 문제가 아니라 pm2 문제인 것 같아요.
    대화보기
    • 화려하게간다
      아닌 나는 왜 안되는거냐고~~~~~~~~~~~~~
    • kimkk
      security for input and output
    • 케굴
      2020-12-26
    • 야옹스
      20211010 Sanitized
    • 졸작완성하자
      211009 완료
    • labis98
      20210730 GOOD!!!
    • Duke
      2021.07.18
    • Jeong Il Haan
      20210423
    • byoonn
      완료
    • chimhyangmoo
      21.02.27
    • jeisyoon
      2021.02.12 App - 출력 정보에 대한 보안 완료
    • 마아앙
      2021.02.10
    • 박소연
      alert태그는 지워지는데 h1이 지워지지 않고 태그가 먹히길래 찾아보니까 지금은 모듈의 디폴트 옵션이 allowedTags에 h1~h6이 전부 들어있기 때문이었어요. 혹시 저처럼 이게 왜 먹히지 하시는분 있을까봐 적어둬요.
    • 손민철
      21/1/1 완료
    • 생활둘기
      2020 12 27
    • kkn1125
      20.12.23 완료~!
    • Yong Hyun Lee
      섬뜩하고 재밌네요!
      완료 201002
    • 박병진
      완료
    • minimal
      update시에는 왜 sanitize를 안해도 되는지 궁금합니다.
    • Jenny Song
      10th.AUG.2020 완료
    • Amousk
      좋은 강의 감사합니다.
    • Katherine Roh
      완료 :)
    • 준바이
      감사합니다
    • 03.12 완료
    • eddylee123456
      복습
    • eddylee123456
      완료
    • 스티븐잡숴
      완료
    • 스티븐잡숴
      완료
    • import.위드
      감사합니다.
      데이터 생성,수정,삭제 + 보안의 내용을 정리해보았습니다.
      공부하시는분들 참고가 되셨으면 좋겠습니다 ^^
      https://blog.naver.com......285
    • 임은정
      완료
    • codinginpain
      완료쓰
    • 강다리
      재밌네요
    • 쑤우
      수강완료. 감사합니다~
    • 굼벵이
      완료
    • CronEB
      완료
    • youngjin.lee
      completed
    • 허공
      190510 감사합니다.
    • 위준우
      완료
    • devs
      저도 이런 오류 났었는데 form action = "/create_process" 부분이나 pathname === '/create'에 '/' 를 빼먹어서 생긴 오류였어요!
      대화보기
      • 홈에서 create 누르면 작성 화면으로 가지 않고 사이트 연결 할 수없다는 오류만 뜹니다.
        not found, undefind 도 안뜨고 구글 오류 메세지로 떠서 어디서 오류가 나는지도 찾을 수가 없습니다.
        어디서 오류가 나는지 아는 방법 없을까요? pm2 에서는 이렇게 출력 됩니다.

        16:53:03 0|main | TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be one of type string or Buffer. Received type object
        16:53:03 0|main | at ServerResponse.end (_http_outgoing.js:690:13)
        16:53:03 0|main | at C:\Users\kim\Desktop\project\main.js:71:15
        16:53:03 0|main | at FSReqWrap.oncomplete (fs.js:141:20)
      graphittie 자세히 보기