ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [생활코딩] Node.js 강의 9일차
    Node.js 2021. 7. 1. 18:53

    App - 출력정보에 대한 보안

    강의내용

     

    8일차에서 오염된 정보가 입력되는걸 막는 법, 오늘은 오염된 정보가 출력되는 것을 막는 법을 배운다. 

    강의 목표 : 

    어떤 사용자에 의해 <script> alert("메롱");</script> 과 같은 오염된 코드가 삽입됐을때 이 코드가 작동하지 않도록해, 다른 사용자들에게 오염된 코드가 노출되지 않도록 한다. 

     

    ' sanitize-html ' 이라는 npm 모듈을 활용한다. (https://www.npmjs.com/package/sanitize-html)

    npm init
    npm install -S sanitize-html 
    

    (  install -S는 작성하는 애플리케이션 환경에 한해 이 모듈이 설치되고 적용된다.)

     

    sanitizeHtml(description,{allowedTags:['h1']}); 와 같이 허용하는 태그를 지정해줄 수도 있다.

    var sanitizeHtml =require('sanitize-html');
    
    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(title,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);
              });
            });

     

     

    sanitize-html 결과

    강의 코드

    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(title,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="text"></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="text" 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;
            console.log(post);
            //파일 이름 바꾸기
            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);
Designed by Tistory.