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. 김철흥
    2024.01.14
    완료!
  2. 어흥
    230702
  3. 감자
    22.12.05 완료
  4. 당당
    2022.10.29
  5. 아캔두잇
    20220810 완료
  6. 키다리아저씨
    220724 완
  7. toonfac
    220714 오후 4시 28분 완료
  8. ForeverJimin
    OMG.. This is literally amazing!
  9. 화려하게간다
    tnlq뭐가 뭔지 모르겠다~~!
  10. 일억개
    전체창으로하면 url 가려서 짜증나네!!!!
  11. kimkk
    input security
    웹브라우저에서 오는 모든 정보는 의심하라.
  12. 케굴
    2021-12-26
  13. pdpd
    212.10.18
  14. 야옹스
    211010 완료!
  15. 졸작완성하자
    211009 완료
  16. labis98
    20210729 good!!!
  17. Duke
    2021.07.18
  18. aminora
    대참사 발생 부정타는 느낌이다
  19. Jeong Il Haan
    20210423
  20. byoonn
    완료
  21. chimhyangmoo
    21.02.26
  22. jeisyoon
    2021.02.12 App - 입력정보에 대한 보안 완료
  23. 마아앙
    2021.02.10
  24. ohhigo
    21/1/25
  25. 이재혁
    ?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가 통째로 덮어쓰기 되어버리네요.
      보안 문제의 심각성을 절감했습니다..ㅋㅋㅋㅋㅋㅋㅋㅋㅋ
      하나하나 입출력 항목을 모두 통제하고 사용자 입장에서 문제 없이 의도하는대로 현출되게 하려면 보통 노력이 필요한게 아니겠네요ㅠㅠ 아직 갈 길이 멀군요.
    graphittie 자세히 보기