everyday com-eat
작성일
2023. 12. 12. 01:29
작성자
갱수터
728x90

입력 정보 보안

ex) 

  • 아이디와 비밀번호를 password.js라는 파일에 저장해서 소스코드 여러 곳에서 사용한다고 가정
//password.js 파일
module.exports = {
    id:'jsg',
    password:'0000'
}

 

  • 사용자가 'localhost:3000/?id=.../password.js' 라 요청 시정보가 고대로 노출된다...

  • ../이라는 경로를 더 입력하여 그보다 상위 디렉터리도, 컴퓨터 전체도 접근가능
  • 이러한 문제가 발생하지 않도록 막는 것이 보안이고, 보안이 중요한 이유이다.
  • 해결방안 : 사용자가 ../같은 상위경로를 포함하여도 강제로 파일명만 사용(parsing)하게 한다
  • 사용자 경로(URI) 분석 node js path parse

 

path 모듈 추가

var path = require('path');

 

 

경로 요청 가져오는 '모든 곳' 수정

  • 외부정보가 들어오는 첫 번째 통로 > readFile
  • 외부정보가 들어오는 두 번째 통로 > 삭제 기능 구현 (delete_process)

readFile 부분 수정

  • path.parse함수 return 값 중 base가 파일이름과 확장자까지 모두 나오니깐 base로 받기
  • 홈 x 페이지, update 화면 2군데
...생략
fs.readdir('./data',function(error, filelist) {
        var filterId = path.parse(queryData.id).base;
        fs.readFile(`data/${filterId}`, 'utf8', function(err, description){
        	...생략...

 

 

delete_process 수정

...생략...
request.on('end', function(data) {
      var post = qs.parse(body);
      var id = post.id;
      var filterId = path.parse(id).base;
      fs.unlink(`data/${filterId}`, function(err){
        ...생략...

 

 

 

결과

제목은 ../password.js로 나오지만? 정보는 undefined로 감춰짐!!

 

 


 

 

 

출력 정보 보안

오염된 정보 출력을 막는 것

ex)

  • 팝업 : create 화면에서 제목="XSS", 내용="<script>alert('hi');</script>" 입력

결과

  • 내용= "<script>location.href = '광고 사이트 주소'</script>" 해서 해당 글 선택시 다른 사이트가 보이거나 다른 사이트로 넘어가거나 다른 사이트의 창이 뜨게 됨...

 

정보 필터링 하기

  • 사용자가 입력한 데이터 중 <script> 태그 아예 지우기 or 실행하게 하지 말고 노출되게 하기
  • '<'이나 '>'을 해석하지 않고 그대로 출력하게 하기  >>> html entities
&lt;script&gt;
location.href = 'https://everyday-com-eat.tistory.com/';
&lt;/script&gt;

결과

 

 

 

외부 모듈 설치

npm 초기화

cd 프로젝트_경로
npm init


~~~엔터~~~

 

 

npm으로 sanitize-html 설치

npm install -S sanitize-html

 

-S : 전역 설치X, 현재 프로젝트에서만 설치

결과

 

 

 

sanitize-html 모듈 추가

var sanitizeHtml = require('sanitize-html');

 

 

 

 

필터링 기능 추가

  • 홈x 상세보기 화면 수정
...생략
fs.readFile(`data/${filterId}`, 'utf8', function(err, description){
          var title = queryData.id;
          var sanitizedTitle = sanitizeHtml(title);
          var sanitizedDescription = sanitizeHtml(description);
          var list = template.list(filelist);
          var html =template.HTML(sanitizedTitle, list,
            `<h2>${sanitizedTitle}</h2><p>${description}</p>`,
            `<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>`);
          ...생략...

 

 

결과

결과 : 제목 invalid_char 오류나서 수정

브라우저에서는 <script>태그와 내용이 아예 필터링되어 안보이는데

파일로는 저장됨!!!

 

 

 

필터링 예외 태그(허용하기)

var sanitizedDescription = sanitizeHtml(description, {
    alloweTags:['h1']
  });

 

728x90