Day-27 Web-Editor, XSS, injection, Hydration Issue

이영주·2022년 6월 15일
0

웹에디터(Web Editor)

웹에디터란 글씨를 진하게 꾸미거나 기울이기 등 꾸미는 도구들을 통틀어서 말한다.

웹에디터 종류로는 매우 많은데 react-quill, ract-draft-wysiwyg, toast UI Editor를 많이 사용한다.

react-quill을 사용하여 실습을 해봤는데

import ReactQuill from "react-quill"

위와 같이 import를 하여 사용한 결과는 오류가 발생하게 되었다..ㅎ

그 이유는 웹에디터는 브라우저에서 실행되기 때문에 서버에서 프리렌더링시에는 읽을 수 없도록
그냥 import를 해주면 안되고 서버렌더링과 브라우저렌더링을 따로 나눠주는 dynamic import를 해줘야한다.
dynamic import를 할 수 있는 도구는 Next.js에서 제공해 주는 기능으로 아래 사진과 같이 작성해주면 된다.

하지만 이렇게 시작부터 라이브러리를 import하게 되면 느려지기 때문에 필요할때만 사용하도록 함수안에 dynamic import를 사용하면 함수를 실행할 때만 적용되기 때문에 빠르고 성능이 좋아진다.

react-quill은 react-hook-form과 같이 사용할 수도 있는데
기존 const { register, handleSubmit, formState } = useForm에서
setValuetrigger를 추가해준다!

setValue는 react-hook-form에 register로 넣어주지 못한 부분에 강제로 value 값을 넣어주기 위함이며
trigger는 form의 모드인 onChange, onClick 등 어떤 것이 실행되었는지 알려주는 기능이다.

웹에디터에서 아무것도 쓰지 않으면 브라우저에는 빈값이 보이지만 사실은 <p><br></p>와 같이 태그가 있는 것이라서 아무것도 쓰지 않을 때는 정말로 빈값이라는 것을 명시해줘야하기 때문에 setValue에는 아래와같이 셋팅을 해줘야 한다.


XSS(Cross Site Script)

웹에디터를 사용하면 아래 사진과 같이 글씨를 꾸밀 수 있는데 이것을 등록하면 이대로 화면에 나타날까?

그럴 줄 알았으나 브라우저에는 아래와 같이 태그와 함께 나타나게 되었다..

이렇게 해결하기 위해 문자열로 인식한 것을 태그로 인식하게 하도록 html 코드 자체를 아래 사진과 같이 적어주게 되면 입력한 그대로 보일 수 있게 된다.

하지만 dangerouslySetInnerHTML을 스크립트로 작성하게 되면 공격을 받기 쉽고 해킹이 쉬워지기 때문에 조심해야 한다.
이렇게 사이트의 취약점을 노려서 사용자 접속 시 악성 코드가 실행되는 XSS(Cross Site Script)를 통해 악의적으로 중요한 정보를 빼가기 때문에 로컬스토리지, 세션스토리지, 쿠키 등에 중요한 정보를 저장하는 것은 좋지 않고 보안에 강한 httpOnly로 하는 것이 좋다.

브라우저에서는 아래와 같이 태그를 직접 입력하지 못하도록 막아놓았으며

프론트 서버에서도 위험한 태그들은 읽히지 않도록 Dompurify.sanitize를 해줘야 한다!
이렇게 해주면 악성 자바스크립트 코드를 막아낼 수 있다.

Injection

Injection이란 조작된 신뢰할 수 없는 데이터가 그대로 전달되어 비정상적인 명령이 실행되는 것을 말한다.

아래 예시를 보면 비밀번호에 1234 || 1===1을 사용하여 1234가 비밀번호가 아닐때 1===1이 true로 처리되어 로그인이 성공되는 말도안되는 현상을 확인할 수 있다.

위와 같은 문제 외에도 OWASP(보안취약점) TOP10을 살펴보면 다양한 문제가 발생하니 항상 Secure Coding을 하는 것이 중요하다.


Hydration Issue

Next.js에서는 프론트 서버에서 프리렌더링 후 브라우저와 결과를 비교(diffing)을 하여 최종결과물을 브라우저에 그려주는데(hydration) 프리렌더링 시에는 태그를 인식하는데 브라우저에서는 내용까지 다 인식하기 때문에 태그 개수가 맞지 않으면 CSS가 다르게 적용되는 이상한 현상이 발생하게 된다.
(브라우저에 그려지는 태그는 4개, 프론트 서버에서 인식하는 태그는 3개일 경우)

따라서 태그 개수를 맞추기 위해 삼항연산자를 사용하여 프론트엔드 서버에서 빈태그가 있도록 설정해야 한다.

profile
= ["꼼꼼한", "프론트엔드 개발자"]

0개의 댓글