Node.js

App - 입력 정보에 대한 보안

수업소개

입력정보와 관련해서 보안적으로 처리해야 할 이슈를 살펴보겠습니다. 

 

 

 

강의

 

 

 

소스코드

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 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;
          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,
              `<h2>${title}</h2>${description}`,
              ` <a href="/create">create</a>
                <a href="/update?id=${title}">update</a>
                <form action="delete_process" method="post">
                  <input type="hidden" name="id" value="${title}">
                  <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. 212.10.18
  2. 야옹스
    211010 완료!
  3. 졸작완성하자
    211009 완료
  4. labis98
    20210729 good!!!
  5. 2021.07.18
  6. aminora
    대참사 발생 부정타는 느낌이다
  7. Jeong Il Haan
    20210423
  8. byoonn
    완료
  9. chimhyangmoo
    21.02.26
  10. jeisyoon
    2021.02.12 App - 입력정보에 대한 보안 완료
  11. 마아앙
    2021.02.10
  12. ohhigo
    21/1/25
  13. 이재혁
    ?id=xx/sysntax/password.js 로 한번 해보세요
    대화보기
    • 생활둘기
      2020 12 26
    • kkn1125
      20.12.23 완료~!
    • 콜라
      20201015 완료
    • Yong Hyun Lee
      완료 201002
    • 박병진
      2020.09.11
    • vampa
      2020.09.11
    • Jenny Song
      1st.AUG.2020 완료
    • Amousk
      좋은 강의 감사합니다.
    • Katherine Roh
      완료 :)
    • 준바이
      감사합니다~
    • eddylee123456
      복습
    • 스티븐잡숴
      크롬 브라우저를 켜고 주소창에

      localhost:3000/?id=xx/password.js
      (x=마침표입니다...마침표마침표/를 입력하면 댓글이 안 달아집니다)

      를 입력햇더니 저는

      <h2>xx/password.js</h2>
      <p>undefined</p>


      의 코드로 화면에 나타나집니다.
      뭔가...크롬에서 알아서 base값만 걸러준걸까요?
      왜 저는 password.js의 문서내용이 안 나타나지는걸까요...허허

      에디터에 문제가 있는걸까요?
      참고로 저는 visual studio code 편집기를 사용하고 있습니다.
    • 문대랭
      전 undefined가 아니라 아예 서버가 막혀버리는데.. 방법이 없을까요?
    • 임은정
      완료
    • 러퍼맨
      var filteredID = path.parse(queryData.id).base;
      ...(`./data/${queryData.id}, ...
      ../ 등의 위험할 수 있는 명령어를 차단하여 보안을 지킨다...새로운게 놀랍네요
    • codinginpain
      완료쓰~
    • 강다리
      runn
    • 쑤우
      수강완료. 감사합니다~
    • 굼벵이
      완료
    • CronEB
      완료
    • 빡조커
      create_process 와 update_process도 적용이 필요합니다.

      상위 디렉토리 모든 파일의 내용을 수정 할 수 있습니다.
    • ThereIsNoWindBag
      이런 기법은 뭐라고 부르나요?
      템플릿 인젝션? 검색해봐도 잘 안나와서요.
    • 고잉고잉
      결국엔 서버의 경로 정보를 숨기다는것이 핵심인거죠?
    • youngjin.lee
      completed
    • 이채
      filteredId를 사용하지 않은 상태에서
      기존 파일명을 '../main.js'로 바꾸고 내용을 입력하지 않고 update하니 main.js가 통째로 덮어쓰기 되어버리네요.
      보안 문제의 심각성을 절감했습니다..ㅋㅋㅋㅋㅋㅋㅋㅋㅋ
      하나하나 입출력 항목을 모두 통제하고 사용자 입장에서 문제 없이 의도하는대로 현출되게 하려면 보통 노력이 필요한게 아니겠네요ㅠㅠ 아직 갈 길이 멀군요.
    • 허공
      190510 감사합니다.
    • 위준우
      완료
    • ㄹㅈw
      감사합니다
    • supernet
      감사합니다.
    • 권문수
      감사합니다!! 보안의 중요성은 어무리 강조하고 강조해도 부족할 지경이네요..
    • Ashed GoodDevil
      그렇겠네요!
      대화보기
      • 나마코엘
        보안고려하니 상당히 개선해야될 부분이 많아지네요..
        a라는 파일이 있는데 b라는 파일의 제목을 a라고 바꾸면 a가 덮어쓰기 되거나 이미 a라는 파일이 있는데 추가로 a라는 파일을 생성할때의 예외처리나 등등.
      • jo_onc
        보안 강의!
        정말 감사합니다.
      • 삼고잉
        첫번째 훑기
      • 박유
        delete_process도 보안처리를 한거라면 같은이유로 update_process 부분도 고쳐주는게 맞는 것이지요?
      • naninem
        보안까지 생각하면 ... 서비스 내놓을때 처리해야할 부분이 어마어마하게 많아지겠다는걸 느꼈습니다.
      • Gimme_Gsuit
        어렵네요 ㅠㅠ ;;;
      graphittie 자세히 보기